Sébastien Dugué a écrit :
1) FUTEX_REQUEUE being able to requeue non-PI futex to PI futex
We're trying to look into that right now.
Humm, let me try to propose a kind of design for a futex_requeue_pi
which does that.
According to the existing code in -mm tree:
static int futex_requeue_pi(u32 __user *uaddr1, u32 __user *uaddr2,
int nr_wake, int nr_requeue, u32 *cmpval) {
1. for the first nr_wake task in the queue
=> call wake_futex(...) /* as today */
2. if it remains some tasks in the list to requeue
a) we must have a pi_state for the futex2.
*) futex2 has an owner and has some waiters (easy case):
=> walk the list hb2->chain, look for a futex_q matching the
key2 (as in lookup_pi_state).
=> retrieve the pi_state attached to this futex_q
OR *) futex2 has an owner but no waiter yet:
=> alloc a pi_state as in lookup_pi_state.
=> set FUTEX_WAITERS flag
OR *) futex2 has no owner and no waiter:
=> set the FUTEX_WAITERS flag on futex2
=> alloc a pi_state _without_ owner.
=> initialize the rtmutex without owner.
b) for each futex_q to requeue
*) requeue the futex_q from hb1 to hb2 (if not the same)
*) set futex_q->pi_state.
*) initialize the rt_mutex_waiter pointed by
futex_q->task->pi_blocked_on with the properties of task
futex_q->task (see futex_wait below).
*) queue it on the wait_list of pi_state->pi_mutex
c) if there was some waiters on futex2 before us
*) take care of prio propagation.
*) if the top_waiter of pi_state->pi_mutex has changed
=> update pi_state->owner->pi_waiters
}
in futex_wait:
==============
static int futex_wait(...) {
...
struct rt_mutex_waiter waiter; /* hum hum */
...
memset(&waiter, 0, sizeof(waiter));
current->pi_blocked_on = &waiter; /* will be used in case of requeue
on a PI-futex */
...
/* just before unqueue_me */
if (q->pi_state) {
/* we were requeued on a PI-futex */
1. do what is done at the end of futex_lock_pi
after "rt_mutex_timed_lock"
2. may be: do what is done at the end of rtmutex_slowlock
(remove ourself from the wait_list, adjust prio, ...)
} else if (!unqueue_me(&q))
...
...
}
in futex_lock_pi:
=================
static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock,
struct hrtimer_sleeper *to) {
...
/* take care of the case where the futex is free (no owner)
but there are some waiters that were requeued (futex_requeue_pi) */
if ((curval & FUTEX_WAITERS) && (curval & FUTEX_TID_MASK) == 0) {
1. make current the futex owner
newval = curval & current->pid;
inc_preempt_count();
curval = futex_atomic_cmpxchg_inatomic(uaddr, FUTEX_WAITERS,
newval);
dec_preempt_count();
/* handle faulty case */
2. search a futex_q whose key match the current one to retrieve
the pi_state.
3. make current the owner of the pi_state:
a) list_add(&pi_state->list, ¤t->pi_state_list);
b) pi_state->owner = current;
4. make current the owner of the pi_mutex:
a) pi_mutex->owner = current;
b) plist_add(&rt_mutex_top_waiter(&pi_mutex)->pi_list_entry,
¤t->pi_waiters);
5. unlock all locks and return
}
...
}
... any kind of comments are welcome ...
Here are some from me:
1. The use of a rt_mutex_waiter in futex_wait does not look very clean
to me... (or not clean at all...). And thus, I wonder if, for example,
mixing futex_q and rt_mutex more closely would not be more helpfull in
this case ??
2. in futex_requeue_pi: how do we know if futex2 is a PI-futex or a
normal futex ? If there are some waiters, we can check if there is a
pi_state linked to a futex_q, but otherwise ?
Proposal: use two separate commands (FUTEX_CMP_REQUEUE and
FUTEX_CMP_REQUEUE_PI) and let the glibc do the choice, as it knows which
kind of mutex/futex it uses.
Thanks.
Running for shelter now !
--
Pierre
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]