Re: owner field in `struct fs'

Andrew Morton (andrewm@uow.edu.au)
Wed, 28 Jun 2000 20:55:45 +1000


Rusty Russell wrote:
>
> No, delete_self_deleting_timer_sync() would look like:
>
> - grab the timerlist_lock
> - detach_timer

You can't naively detach the timer at this point. This is because its
handler may have already run. If it has, you're reading & writing freed
memory. (You covered this below).

> - if that succeeds, release lock
> - if that failed:
> - if timer is running now, release lock, spin until its done
> - if timer isn't running, release lock, BUG()
>
> This is required, because if you call `del_timer(&timer)' you *need*
> to know (because you have your own spinlocks) that it hasn't run yet,
> or is running at the moment. That's because if it's finished running,
> you might now be deleting a completely unrelated timer...

Good point. It must be either pending or running. And if it's running
you can't dereference `timer' because it may be freed. Hence the caller
must use spinlocks which block the handler prior to it freeing the
storage. And you also need to determine by some external means whether
the handler has run. Blah.

int timer_live;
spinlock_t my_lock;

handler()
{
spin_lock(my_lock);
kfree(timer);
timer_live = 0;
spin_unlock(my_lock);
}

mainline()
{
spin_lock_bh(my_lock);
if (timer_live)
if (del_timer(timer))
kfree(timer);
spin_unlock_bh(my_lock);
/* handler could be running now */
}

delete_self_deleting_timer_sync() couldn't be used here - it would spin
forever waiting for the handler to complete, due to `my_lock' being held
by the caller. delete_self_deleting_timer_sync() would need to be
passed a reference to my_lock so it can be unlocked while timerlist_lock
is held. Unpleasing.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/