lkml.org 
[lkml]   [2009]   [Jan]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [RFC v4] wait: prevent waiter starvation in __wait_on_bit_lock
    On 01/23, Oleg Nesterov wrote:
    >
    > It is no that I think this new helper is really needed for this
    > particular case, personally I agree with the patch you sent.
    >
    > But if we have other places with the similar problem, then perhaps
    > it is better to introduce the special finish_wait_exclusive() or
    > whatever.

    To clarify, I suggest something like this.

    int finish_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait,
    int ret, int state, void *key)
    {
    unsigned long flags;

    __set_current_state(TASK_RUNNING);

    if (ret || !list_empty_careful(&wait->task_list)) {
    spin_lock_irqsave(&q->lock, flags);
    if (list_empty(&wait->task_list))
    __wake_up_common(q, state, 1, key);
    else
    list_del_init(&wait->task_list);
    spin_unlock_irqrestore(&q->lock, flags);
    }

    return ret;
    }

    Now, __wait_on_bit_lock() becomes:

    int __sched
    __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q,
    int (*action)(void *), unsigned mode)
    {
    int ret = 0;

    do {
    prepare_to_wait_exclusive(wq, &q->wait, mode);
    if (test_bit(q->key.bit_nr, q->key.flags) &&
    (ret = (*action)(q->key.flags))
    break;
    } while (test_and_set_bit(q->key.bit_nr, q->key.flags));

    return finish_wait_exclusive(wq, &q->wait, ret, mode, &q->key);
    }

    And __wait_event_interruptible_exclusive:

    #define __wait_event_interruptible_exclusive(wq, condition, ret) \
    do { \
    DEFINE_WAIT(__wait); \
    \
    for (;;) { \
    prepare_to_wait_exclusive(&wq, &__wait, \
    TASK_INTERRUPTIBLE); \
    if (condition) \
    break; \
    if (!signal_pending(current)) { \
    schedule(); \
    continue; \
    } \
    ret = -ERESTARTSYS; \
    break; \
    } \
    finish_wait_exclusive(&wq, &__wait, \
    ret, TASK_INTERRUPTIBLE, NULL); \
    } while (0)

    But I can't convince myself this is what we really want. So I am not
    sending the patch. And yes, we have to check ret twice.

    Oleg.



    \
     
     \ /
      Last update: 2009-01-23 14:35    [W:5.304 / U:0.376 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site