@@ -270,37 +270,6 @@ void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
270
270
}
271
271
EXPORT_SYMBOL (finish_wait );
272
272
273
- /**
274
- * abort_exclusive_wait - abort exclusive waiting in a queue
275
- * @q: waitqueue waited on
276
- * @wait: wait descriptor
277
- * @key: key to identify a wait bit queue or %NULL
278
- *
279
- * Sets current thread back to running state and removes
280
- * the wait descriptor from the given waitqueue if still
281
- * queued.
282
- *
283
- * Wakes up the next waiter if the caller is concurrently
284
- * woken up through the queue.
285
- *
286
- * This prevents waiter starvation where an exclusive waiter
287
- * aborts and is woken up concurrently and no one wakes up
288
- * the next waiter.
289
- */
290
- void abort_exclusive_wait (wait_queue_head_t * q , wait_queue_t * wait , void * key )
291
- {
292
- unsigned long flags ;
293
-
294
- __set_current_state (TASK_RUNNING );
295
- spin_lock_irqsave (& q -> lock , flags );
296
- if (!list_empty (& wait -> task_list ))
297
- list_del_init (& wait -> task_list );
298
- else if (waitqueue_active (q ))
299
- __wake_up_locked_key (q , TASK_NORMAL , key );
300
- spin_unlock_irqrestore (& q -> lock , flags );
301
- }
302
- EXPORT_SYMBOL (abort_exclusive_wait );
303
-
304
273
int autoremove_wake_function (wait_queue_t * wait , unsigned mode , int sync , void * key )
305
274
{
306
275
int ret = default_wake_function (wait , mode , sync , key );
@@ -438,20 +407,29 @@ int __sched
438
407
__wait_on_bit_lock (wait_queue_head_t * wq , struct wait_bit_queue * q ,
439
408
wait_bit_action_f * action , unsigned mode )
440
409
{
441
- do {
442
- int ret ;
410
+ int ret = 0 ;
443
411
412
+ for (;;) {
444
413
prepare_to_wait_exclusive (wq , & q -> wait , mode );
445
- if (!test_bit (q -> key .bit_nr , q -> key .flags ))
446
- continue ;
447
- ret = action (& q -> key , mode );
448
- if (!ret )
449
- continue ;
450
- abort_exclusive_wait (wq , & q -> wait , & q -> key );
451
- return ret ;
452
- } while (test_and_set_bit (q -> key .bit_nr , q -> key .flags ));
453
- finish_wait (wq , & q -> wait );
454
- return 0 ;
414
+ if (test_bit (q -> key .bit_nr , q -> key .flags )) {
415
+ ret = action (& q -> key , mode );
416
+ /*
417
+ * See the comment in prepare_to_wait_event().
418
+ * finish_wait() does not necessarily takes wq->lock,
419
+ * but test_and_set_bit() implies mb() which pairs with
420
+ * smp_mb__after_atomic() before wake_up_page().
421
+ */
422
+ if (ret )
423
+ finish_wait (wq , & q -> wait );
424
+ }
425
+ if (!test_and_set_bit (q -> key .bit_nr , q -> key .flags )) {
426
+ if (!ret )
427
+ finish_wait (wq , & q -> wait );
428
+ return 0 ;
429
+ } else if (ret ) {
430
+ return ret ;
431
+ }
432
+ }
455
433
}
456
434
EXPORT_SYMBOL (__wait_on_bit_lock );
457
435
0 commit comments