Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: sched/wait: Add wait_event_lock_irq_timeout for TASK_UNINTERRUPTIBLE usage

Short of reverting commit 00d909a10710 ("scsi: target: Make the session
shutdown code also wait for commands that are being aborted") for v4.19,
target-core needs a wait_event_t macro can be executed using
TASK_UNINTERRUPTIBLE to function correctly with existing fabric drivers that
expect to run with signals pending during session shutdown and active se_cmd
I/O quiesce.

The most notable is iscsi-target/iser-target, while ibmvscsi_tgt invokes
session shutdown logic from userspace via configfs attribute that could also
potentially have signals pending.

So go ahead and introduce wait_event_lock_irq_timeout() to achieve this, and
update + rename __wait_event_lock_irq_timeout() to make it accept 'state' as a
parameter.

Fixes: 00d909a10710 ("scsi: target: Make the session shutdown code also wait for commands that are being aborted")
Cc: <stable@vger.kernel.org> # v4.19+
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Mike Christie <mchristi@redhat.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Reviewed-by: Bryant G. Ly <bly@catalogicsoftware.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Nicholas Bellinger and committed by
Martin K. Petersen
25ab0bc3 0b4aafc3

+15 -5
+15 -5
include/linux/wait.h
··· 1052 1052 __ret; \ 1053 1053 }) 1054 1054 1055 - #define __wait_event_interruptible_lock_irq_timeout(wq_head, condition, \ 1056 - lock, timeout) \ 1055 + #define __wait_event_lock_irq_timeout(wq_head, condition, lock, timeout, state) \ 1057 1056 ___wait_event(wq_head, ___wait_cond_timeout(condition), \ 1058 - TASK_INTERRUPTIBLE, 0, timeout, \ 1057 + state, 0, timeout, \ 1059 1058 spin_unlock_irq(&lock); \ 1060 1059 __ret = schedule_timeout(__ret); \ 1061 1060 spin_lock_irq(&lock)); ··· 1088 1089 ({ \ 1089 1090 long __ret = timeout; \ 1090 1091 if (!___wait_cond_timeout(condition)) \ 1091 - __ret = __wait_event_interruptible_lock_irq_timeout( \ 1092 - wq_head, condition, lock, timeout); \ 1092 + __ret = __wait_event_lock_irq_timeout( \ 1093 + wq_head, condition, lock, timeout, \ 1094 + TASK_INTERRUPTIBLE); \ 1095 + __ret; \ 1096 + }) 1097 + 1098 + #define wait_event_lock_irq_timeout(wq_head, condition, lock, timeout) \ 1099 + ({ \ 1100 + long __ret = timeout; \ 1101 + if (!___wait_cond_timeout(condition)) \ 1102 + __ret = __wait_event_lock_irq_timeout( \ 1103 + wq_head, condition, lock, timeout, \ 1104 + TASK_UNINTERRUPTIBLE); \ 1093 1105 __ret; \ 1094 1106 }) 1095 1107