a substantial percentage of __wake_up() calls are done on empty waitqueues- the percentage in a typical system is around 50% but can be higher undervarious loads. The attached waitqueue-2.4.0-test7-A1 patch optimizeswake_up() to check wether the waitqueue is empty before calling__wake_up(). This optimization is especially useful on SMP systems - thewaitqueue spinlock is not taken thus causes no cacheline ping-pong. Butthere are benefits on UP systems as well, the cli/sti pair in __wake_up isnot executed in these cases and we avoid the function call as well.

the wake_up() variants could be optimized further if we didnt allow NULLpointers being passed to wake_up() - but this i think is a 2.5 item as itchanges the wake_up() interface. I've done this optimization too, andthere are not that many places that pass NULL to wake_up() - but ithappens often enough to cause trouble if done now.

there is the question of synchronization with the waitqueue lock on SMPsystems - the waitqueue_active() check goes outside the waitqueuespinlock, but i think this is safe. I didnt see any problems whatsoever.

-#define wake_up(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)-#define wake_up_all(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)-#define wake_up_sync(x) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)-#define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)-#define wake_up_interruptible_all(x) __wake_up((x),TASK_INTERRUPTIBLE)-#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)+/*+ * Subtle. We skip the wakeup if the queue is empty, but we do+ * not synchronize with the waitqueue spinlock. The reason for+ * this is performance, a big percentage of wakeups goes to empty+ * waitqueues. The effect of this is that we might not notice+ * 'just being added' entries, but this is not a problem, it's+ * effectively the same as if this CPU was 'very fast'.+ */+#define _wake_up(q,mode) \+ do { if (q && waitqueue_active(q)) __wake_up((q), (mode)); } while (0)+#define _wake_up_sync(q,mode) \+ do { if (q && waitqueue_active(q)) __wake_up_sync((q), (mode)); } while (0)