On 2018-03-08 13:54:17 [-0600], Corey Minyard wrote:...
still no need to make it more expensive if it can be avoided.It will work but I don't think pushing this into workqueue/tasklet is aTrue, but this is an uncommon and already fairly expensive operation being
good idea. You want to wakeup all waiters on waitqueue X (probably one
waiter) and instead there is one one wakeup + ctx-switch which does the
final wakeup.
done. Adding a context switch doesn't seem that bad.
Look at this:But now I had an idea: swake_up_all() could iterate over list andThat sounds promising, but where does wake_up_q() get called? No matter
instead performing wakes it would just wake_q_add() the tasks. Drop the
lock and then wake_up_q(). So in case there is wakeup pending and the
task removed itself from the list then the task may observe a spurious
wakeup.
what
it's an expensive operation and I'm not sure where you would put it in this
case.
void swake_up(struct swait_queue_head *q)
{
@@ -66,25 +62,14 @@ EXPORT_SYMBOL(swake_up);
*/
void swake_up_all(struct swait_queue_head *q)
{
- struct swait_queue *curr;
- LIST_HEAD(tmp);
+ unsigned long flags;
+ DEFINE_WAKE_Q(wq);
- WARN_ON(irqs_disabled());
- raw_spin_lock_irq(&q->lock);
- list_splice_init(&q->task_list, &tmp);
- while (!list_empty(&tmp)) {
- curr = list_first_entry(&tmp, typeof(*curr), task_list);
+ raw_spin_lock_irqsave(&q->lock, flags);
+ swake_add_all_wq(q, &wq);
+ raw_spin_unlock_irqrestore(&q->lock, flags);
- wake_up_state(curr->task, TASK_NORMAL);
- list_del_init(&curr->task_list);
-
- if (list_empty(&tmp))
- break;
-
- raw_spin_unlock_irq(&q->lock);
- raw_spin_lock_irq(&q->lock);
- }
- raw_spin_unlock_irq(&q->lock);
+ wake_up_q(&wq);
}
EXPORT_SYMBOL(swake_up_all);
I had another idea. This is only occurring if RT is not enabled, becauseWith the patch above I have puzzle part which would allow to use swait
with
RT all the irq disable things go away and you are generally running in task
context. So why not have a different version of swake_up_all() for non-RT
that does work from irqs-off context?
based completions upstream. That ifdef would probably not help.
-coreySebastian