Small performance optimization: wake up IO/processing threads in LIFO order.
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Tue, 30 Jun 2009 16:13:48 +0000 (16:13 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Tue, 30 Jun 2009 16:13:48 +0000 (16:13 +0000)
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@928 d57e44dd-8a1f-0410-8b47-8ef2f437770f

iscsi-scst/kernel/nthread.c
scst/include/scst.h
scst/src/dev_handlers/scst_user.c
scst/src/scst_targ.c

index da557ec..04b733f 100644 (file)
@@ -974,7 +974,7 @@ int istrd(void *arg)
                init_waitqueue_entry(&wait, current);
 
                if (!test_rd_list()) {
-                       add_wait_queue_exclusive(&iscsi_rd_waitQ, &wait);
+                       add_wait_queue_exclusive_head(&iscsi_rd_waitQ, &wait);
                        for (;;) {
                                set_current_state(TASK_INTERRUPTIBLE);
                                if (test_rd_list())
@@ -1662,7 +1662,7 @@ int istwr(void *arg)
                init_waitqueue_entry(&wait, current);
 
                if (!test_wr_list()) {
-                       add_wait_queue_exclusive(&iscsi_wr_waitQ, &wait);
+                       add_wait_queue_exclusive_head(&iscsi_wr_waitQ, &wait);
                        for (;;) {
                                set_current_state(TASK_INTERRUPTIBLE);
                                if (test_wr_list())
index 3b11b26..68b0435 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
+#include <linux/wait.h>
 
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -3075,4 +3076,20 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd,
  */
 int scst_obtain_device_parameters(struct scst_device *dev);
 
+/*
+ * Has to be put here open coded, because Linux doesn't have equivalent, which
+ * allows exclusive wake ups of threads in LIFO order. We need it to let (yet)
+ * unneeded threads sleep and not pollute CPU cache by their stacks. 
+ */
+static inline void add_wait_queue_exclusive_head(wait_queue_head_t *q,
+       wait_queue_t *wait)
+{
+       unsigned long flags;
+
+       wait->flags |= WQ_FLAG_EXCLUSIVE;
+       spin_lock_irqsave(&q->lock, flags);
+       __add_wait_queue(q, wait);
+       spin_unlock_irqrestore(&q->lock, flags);
+}
+
 #endif /* __SCST_H */
index 4432f63..0160a18 100644 (file)
@@ -1745,7 +1745,8 @@ static int dev_user_get_next_cmd(struct scst_user_dev *dev,
 
        while (1) {
                if (!test_cmd_lists(dev)) {
-                       add_wait_queue_exclusive(&dev->cmd_lists.cmd_list_waitQ,
+                       add_wait_queue_exclusive_head(
+                               &dev->cmd_lists.cmd_list_waitQ,
                                &wait);
                        for (;;) {
                                set_current_state(TASK_INTERRUPTIBLE);
index ef6539b..05105ed 100644 (file)
@@ -3735,7 +3735,8 @@ int scst_cmd_thread(void *arg)
                init_waitqueue_entry(&wait, current);
 
                if (!test_cmd_lists(p_cmd_lists)) {
-                       add_wait_queue_exclusive(&p_cmd_lists->cmd_list_waitQ,
+                       add_wait_queue_exclusive_head(
+                               &p_cmd_lists->cmd_list_waitQ,
                                &wait);
                        for (;;) {
                                set_current_state(TASK_INTERRUPTIBLE);