From c63c44e4f090bd7d0dd24cdd2f702ba4e8bcb2bc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Feb 2019 03:07:02 +0000 Subject: [PATCH 1/5] vdisk_fileio: Add additioinal consistency check for asynchronous I/O git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7918 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/dev_handlers/scst_vdisk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 9ec6e4af6..884f6d827 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -3269,6 +3269,8 @@ static void fileio_async_complete(struct kiocb *iocb, long ret, long ret2) struct vdisk_cmd_params *p = container_of(iocb, typeof(*p), async.iocb); struct scst_cmd *cmd = p->cmd; + WARN_ON_ONCE(ret >= 0 && ret != cmd->bufflen); + if (ret < 0 && scst_cmd_get_data_direction(cmd) & SCST_DATA_WRITE) scst_set_cmd_error(cmd, From 70150cb9129db9f5938c590a3629259adb17a2e0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Feb 2019 03:07:54 +0000 Subject: [PATCH 2/5] scst: Remove the exec_sync flag Since all device handlers have at least one asynchronous mode, remove the exec_sync flag. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7919 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- doc/scst_pg.sgml | 10 ++-------- scst/include/scst.h | 11 ++--------- scst/src/dev_handlers/scst_vdisk.c | 2 -- scst/src/scst_targ.c | 2 +- 4 files changed, 5 insertions(+), 20 deletions(-) diff --git a/doc/scst_pg.sgml b/doc/scst_pg.sgml index eb2475b12..c75dddf82 100644 --- a/doc/scst_pg.sgml +++ b/doc/scst_pg.sgml @@ -563,8 +563,6 @@ struct scst_dev_type unsigned no_proc:1; - unsigned exec_sync:1; - unsigned pr_cmds_notifications:1; int threads_num; @@ -607,9 +605,6 @@ execution in the atomic (non-sleeping) context. -If this function provides sync execution, you should set -exec_sync flag and consider to setup dedicated threads by -setting 0. +If this function provides sync execution, you should consider to setup +dedicated threads by setting 0. Optional, if not set, the commands will be sent directly to SCSI device. diff --git a/scst/include/scst.h b/scst/include/scst.h index 78c0d1973..b96a778ee 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -1381,12 +1381,6 @@ struct scst_dev_type { unsigned no_proc:1; #endif - /* - * Should be true, if exec() is synchronous. This is a hint to SCST core - * to optimize commands order management. - */ - unsigned exec_sync:1; - /* * Should be set if the device wants to receive notification of * Persistent Reservation commands (PR OUT only) @@ -1454,9 +1448,8 @@ struct scst_dev_type { * - SCST_EXEC_NOT_COMPLETED - the cmd should be sent to SCSI * mid-level. * - * If this function provides sync execution, you should set - * exec_sync flag and consider to setup dedicated threads by - * setting threads_num > 0. + * If this function provides sync execution, you should to set up + * dedicated threads by setting threads_num > 0. * * Dev handlers implementing internal queuing in their exec() callback * should call scst_check_local_events() just before the actual diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 884f6d827..8899bddeb 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -760,7 +760,6 @@ static vdisk_op_fn nullio_ops[256]; static struct scst_dev_type vdisk_file_devtype = { .name = "vdisk_fileio", .type = TYPE_DISK, - .exec_sync = 1, .threads_num = -1, .parse_atomic = 1, .dev_done_atomic = 1, @@ -922,7 +921,6 @@ static struct scst_dev_type vdisk_null_devtype = { static struct scst_dev_type vcdrom_devtype = { .name = "vcdrom", .type = TYPE_ROM, - .exec_sync = 1, .threads_num = -1, .parse_atomic = 1, .dev_done_atomic = 1, diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 0c23accc9..651b45de4 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -953,7 +953,7 @@ int scst_pre_parse(struct scst_cmd *cmd) #ifdef CONFIG_SCST_STRICT_SERIALIZING cmd->inc_expected_sn_on_done = 1; #else - cmd->inc_expected_sn_on_done = devt->exec_sync || cmd->cmd_naca || + cmd->inc_expected_sn_on_done = cmd->cmd_naca || (!dev->has_own_order_mgmt && (dev->queue_alg == SCST_QUEUE_ALG_0_RESTRICTED_REORDER || cmd->queue_type == SCST_CMD_QUEUE_ORDERED)); From 6dc08eb5b6b27f9401d289631369ebf53b4d766b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Feb 2019 03:08:39 +0000 Subject: [PATCH 3/5] scst_vdisk: Avoid that fileio_alloc_and_parse() locks up in tasklet context if low on memory git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7920 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/dev_handlers/scst_vdisk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 8899bddeb..229f6a58d 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -3092,7 +3092,8 @@ static int fileio_alloc_and_parse(struct scst_cmd *cmd) TRACE_ENTRY(); - p = kmem_cache_zalloc(vdisk_cmd_param_cachep, cmd->cmd_gfp_mask); + p = kmem_cache_zalloc(vdisk_cmd_param_cachep, + in_interrupt() ? GFP_ATOMIC : cmd->cmd_gfp_mask); if (!p) { scst_set_busy(cmd); goto out_err; From aa6c9558e821aade778838bd672fad2c0d7d1fbd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Feb 2019 03:10:12 +0000 Subject: [PATCH 4/5] scst: Introduce enum scst_exec_res This patch does not change any functionality. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7921 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst.h | 21 +++++++-------- scst/src/dev_handlers/scst_disk.c | 13 ++++----- scst/src/dev_handlers/scst_modisk.c | 6 ++--- scst/src/dev_handlers/scst_tape.c | 6 ++--- scst/src/dev_handlers/scst_user.c | 4 +-- scst/src/dev_handlers/scst_vdisk.c | 27 ++++++++++--------- scst/src/scst_copy_mgr.c | 10 ++++--- scst/src/scst_lib.c | 4 +-- scst/src/scst_priv.h | 11 ++++---- scst/src/scst_targ.c | 42 +++++++++++++++-------------- 10 files changed, 75 insertions(+), 69 deletions(-) diff --git a/scst/include/scst.h b/scst/include/scst.h index b96a778ee..68027ec4b 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -448,17 +448,16 @@ enum scst_exec_context { ** Return codes for dev handler's exec() *************************************************************/ -/* - * The cmd is completed, go to other ones. It doesn't necessary to be really - * completed, it can still be being processed. This code means that SCST - * core should start performing post processing actions for this cmd, like - * increase SN and reactivate deferred commands, if allowed, and start - * processing other commands. - */ -#define SCST_EXEC_COMPLETED 0 +enum scst_exec_res { + /* + * The device handler has finished executing the command or has + * started executing the command asynchronously. + */ + SCST_EXEC_COMPLETED = 0, -/* The cmd should continue staying on the EXEC phase */ -#define SCST_EXEC_NOT_COMPLETED 1 + /* Pass through the command to the SCSI mid-level. */ + SCST_EXEC_NOT_COMPLETED = 1, +}; /************************************************************* ** Session initialization phases @@ -1458,7 +1457,7 @@ struct scst_dev_type { * OPTIONAL, if not set, the commands will be sent directly to SCSI * device. */ - int (*exec)(struct scst_cmd *cmd); + enum scst_exec_res (*exec)(struct scst_cmd *cmd); /* * Called to notify dev handler about the result of cmd execution diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c index 01120b90b..e5ede7d66 100644 --- a/scst/src/dev_handlers/scst_disk.c +++ b/scst/src/dev_handlers/scst_disk.c @@ -45,10 +45,10 @@ static int disk_attach(struct scst_device *dev); static void disk_detach(struct scst_device *dev); static int disk_parse(struct scst_cmd *cmd); -static int disk_perf_exec(struct scst_cmd *cmd); +static enum scst_exec_res disk_perf_exec(struct scst_cmd *cmd); static int disk_done(struct scst_cmd *cmd); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) -static int disk_exec(struct scst_cmd *cmd); +static enum scst_exec_res disk_exec(struct scst_cmd *cmd); static bool disk_on_sg_tablesize_low(struct scst_cmd *cmd); #endif @@ -396,9 +396,10 @@ out_complete: } /* Executes command and split CDB, if necessary */ -static int disk_exec(struct scst_cmd *cmd) +static enum scst_exec_res disk_exec(struct scst_cmd *cmd) { - int res, rc; + enum scst_exec_res res; + int rc; struct disk_work work; struct scst_device *dev = cmd->dev; unsigned int offset, cur_len; /* in blocks */ @@ -583,9 +584,9 @@ out_error: #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) */ -static int disk_perf_exec(struct scst_cmd *cmd) +static enum scst_exec_res disk_perf_exec(struct scst_cmd *cmd) { - int res; + enum scst_exec_res res; int opcode = cmd->cdb[0]; TRACE_ENTRY(); diff --git a/scst/src/dev_handlers/scst_modisk.c b/scst/src/dev_handlers/scst_modisk.c index 61cb17f3f..a63529e28 100644 --- a/scst/src/dev_handlers/scst_modisk.c +++ b/scst/src/dev_handlers/scst_modisk.c @@ -45,7 +45,7 @@ static int modisk_attach(struct scst_device *); static void modisk_detach(struct scst_device *); static int modisk_parse(struct scst_cmd *); static int modisk_done(struct scst_cmd *); -static int modisk_perf_exec(struct scst_cmd *); +static enum scst_exec_res modisk_perf_exec(struct scst_cmd *); static struct scst_dev_type modisk_devtype = { .name = MODISK_NAME, @@ -308,9 +308,9 @@ static int modisk_done(struct scst_cmd *cmd) return res; } -static int modisk_perf_exec(struct scst_cmd *cmd) +static enum scst_exec_res modisk_perf_exec(struct scst_cmd *cmd) { - int res = SCST_EXEC_NOT_COMPLETED; + enum scst_exec_res res = SCST_EXEC_NOT_COMPLETED; int opcode = cmd->cdb[0]; TRACE_ENTRY(); diff --git a/scst/src/dev_handlers/scst_tape.c b/scst/src/dev_handlers/scst_tape.c index c8224b7ee..fa240094d 100644 --- a/scst/src/dev_handlers/scst_tape.c +++ b/scst/src/dev_handlers/scst_tape.c @@ -50,7 +50,7 @@ static int tape_attach(struct scst_device *); static void tape_detach(struct scst_device *); static int tape_parse(struct scst_cmd *); static int tape_done(struct scst_cmd *); -static int tape_perf_exec(struct scst_cmd *); +static enum scst_exec_res tape_perf_exec(struct scst_cmd *); static struct scst_dev_type tape_devtype = { .name = TAPE_NAME, @@ -336,9 +336,9 @@ out: return res; } -static int tape_perf_exec(struct scst_cmd *cmd) +static enum scst_exec_res tape_perf_exec(struct scst_cmd *cmd) { - int res = SCST_EXEC_NOT_COMPLETED; + enum scst_exec_res res = SCST_EXEC_NOT_COMPLETED; int opcode = cmd->cdb[0]; TRACE_ENTRY(); diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 8fb443814..d7ddca08b 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -913,10 +913,10 @@ out: return; } -static int dev_user_exec(struct scst_cmd *cmd) +static enum scst_exec_res dev_user_exec(struct scst_cmd *cmd) { struct scst_user_cmd *ucmd = cmd->dh_priv; - int res = SCST_EXEC_COMPLETED; + enum scst_exec_res res = SCST_EXEC_COMPLETED; TRACE_ENTRY(); diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 229f6a58d..04e5201a3 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -331,10 +331,10 @@ static int vcdrom_get_supported_opcodes(struct scst_cmd *cmd, static int vdisk_parse(struct scst_cmd *); static int vcdrom_parse(struct scst_cmd *); static int non_fileio_parse(struct scst_cmd *); -static int fileio_exec(struct scst_cmd *cmd); -static int vcdrom_exec(struct scst_cmd *cmd); -static int blockio_exec(struct scst_cmd *cmd); -static int nullio_exec(struct scst_cmd *cmd); +static enum scst_exec_res fileio_exec(struct scst_cmd *cmd); +static enum scst_exec_res vcdrom_exec(struct scst_cmd *cmd); +static enum scst_exec_res blockio_exec(struct scst_cmd *cmd); +static enum scst_exec_res nullio_exec(struct scst_cmd *cmd); static void blockio_on_alua_state_change_start(struct scst_device *dev, enum scst_tg_state old_state, enum scst_tg_state new_state); static void blockio_on_alua_state_change_finish(struct scst_device *dev, @@ -3160,9 +3160,10 @@ out: return res; } -static int vdev_do_job(struct scst_cmd *cmd, const vdisk_op_fn *ops) +static enum scst_exec_res vdev_do_job(struct scst_cmd *cmd, + const vdisk_op_fn *ops) { - int res; + enum scst_exec_res res; uint8_t *cdb = cmd->cdb; int opcode = cdb[0]; struct vdisk_cmd_params *p = cmd->dh_priv; @@ -3224,7 +3225,7 @@ out_invalid_opcode: goto out_compl; } -static int fileio_exec(struct scst_cmd *cmd) +static enum scst_exec_res fileio_exec(struct scst_cmd *cmd) { struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; const vdisk_op_fn *ops = virt_dev->vdev_devt->devt_priv; @@ -3459,12 +3460,12 @@ out: return res; } -static int blockio_exec(struct scst_cmd *cmd) +static enum scst_exec_res blockio_exec(struct scst_cmd *cmd) { struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; const vdisk_op_fn *ops = virt_dev->vdev_devt->devt_priv; struct vdisk_cmd_params p; - int res; + enum scst_exec_res res; EXTRACHECKS_BUG_ON(!ops); @@ -3505,12 +3506,12 @@ err: goto out; } -static int nullio_exec(struct scst_cmd *cmd) +static enum scst_exec_res nullio_exec(struct scst_cmd *cmd) { struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; const vdisk_op_fn *ops = virt_dev->vdev_devt->devt_priv; struct vdisk_cmd_params p; - int res; + enum scst_exec_res res; EXTRACHECKS_BUG_ON(!ops); @@ -3533,9 +3534,9 @@ err: goto out; } -static int vcdrom_exec(struct scst_cmd *cmd) +static enum scst_exec_res vcdrom_exec(struct scst_cmd *cmd) { - int res = SCST_EXEC_COMPLETED; + enum scst_exec_res res = SCST_EXEC_COMPLETED; int opcode = cmd->cdb[0]; struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; diff --git a/scst/src/scst_copy_mgr.c b/scst/src/scst_copy_mgr.c index d57bc4a36..4f4136274 100644 --- a/scst/src/scst_copy_mgr.c +++ b/scst/src/scst_copy_mgr.c @@ -1616,9 +1616,10 @@ out: return; } -int scst_cm_ext_copy_exec(struct scst_cmd *ec_cmd) +enum scst_exec_res scst_cm_ext_copy_exec(struct scst_cmd *ec_cmd) { - int res = SCST_EXEC_COMPLETED, rc; + enum scst_exec_res res = SCST_EXEC_COMPLETED; + int rc; struct scst_cm_ec_cmd_priv *priv = ec_cmd->cmd_data_descriptors; TRACE_ENTRY(); @@ -2273,9 +2274,10 @@ out: return; } -int scst_cm_rcv_copy_res_exec(struct scst_cmd *cmd) +enum scst_exec_res scst_cm_rcv_copy_res_exec(struct scst_cmd *cmd) { - int res = SCST_EXEC_COMPLETED, action; + enum scst_exec_res res = SCST_EXEC_COMPLETED; + int action; TRACE_ENTRY(); diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 4952ca481..d34c54481 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -6859,9 +6859,9 @@ out_finish: goto out; } -int scst_cmp_wr_local(struct scst_cmd *cmd) +enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd) { - int res = SCST_EXEC_COMPLETED; + enum scst_exec_res res = SCST_EXEC_COMPLETED; struct scst_cwr_priv *cwrp; uint8_t read16_cdb[16]; struct scst_cmd *rcmd; diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index 063a7f083..a5bab7e9e 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -862,7 +862,7 @@ void scst_unthrottle_cmd(struct scst_cmd *cmd); int scst_do_internal_parsing(struct scst_cmd *cmd); int scst_parse_descriptors(struct scst_cmd *cmd); -int scst_cmp_wr_local(struct scst_cmd *cmd); +enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd); int scst_pr_init(struct scst_device *dev); void scst_pr_cleanup(struct scst_device *dev); @@ -912,8 +912,8 @@ bool scst_cm_on_del_lun(struct scst_acg_dev *acg_dev, int scst_cm_parse_descriptors(struct scst_cmd *cmd); void scst_cm_free_descriptors(struct scst_cmd *cmd); -int scst_cm_ext_copy_exec(struct scst_cmd *cmd); -int scst_cm_rcv_copy_res_exec(struct scst_cmd *cmd); +enum scst_exec_res scst_cm_ext_copy_exec(struct scst_cmd *cmd); +enum scst_exec_res scst_cm_rcv_copy_res_exec(struct scst_cmd *cmd); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) void sess_cm_list_id_cleanup_work_fn(void *p); @@ -965,11 +965,12 @@ static inline int scst_cm_parse_descriptors(struct scst_cmd *cmd) } static inline void scst_cm_free_descriptors(struct scst_cmd *cmd) {} -static inline int scst_cm_ext_copy_exec(struct scst_cmd *cmd) +static inline enum scst_exec_res scst_cm_ext_copy_exec(struct scst_cmd *cmd) { return SCST_EXEC_NOT_COMPLETED; } -static inline int scst_cm_rcv_copy_res_exec(struct scst_cmd *cmd) + +static inline enum scst_exec_res scst_cm_rcv_copy_res_exec(struct scst_cmd *cmd) { return SCST_EXEC_NOT_COMPLETED; } diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 651b45de4..628239d98 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -2247,9 +2247,9 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state, return; } -static int scst_report_luns_local(struct scst_cmd *cmd) +static enum scst_exec_res scst_report_luns_local(struct scst_cmd *cmd) { - int res = SCST_EXEC_COMPLETED; + enum scst_exec_res res = SCST_EXEC_COMPLETED; int dev_cnt = 0; int buffer_size; int i; @@ -2348,9 +2348,9 @@ out_put_err: goto out_compl; } -static int scst_request_sense_local(struct scst_cmd *cmd) +static enum scst_exec_res scst_request_sense_local(struct scst_cmd *cmd) { - int res = SCST_EXEC_COMPLETED; + enum scst_exec_res res = SCST_EXEC_COMPLETED; struct scst_tgt_dev *tgt_dev = cmd->tgt_dev; uint8_t *buffer; int buffer_size = 0, sl = 0; @@ -2720,9 +2720,9 @@ out_err_put: goto out_compl; } -static int scst_maintenance_in(struct scst_cmd *cmd) +static enum scst_exec_res scst_maintenance_in(struct scst_cmd *cmd) { - int res; + enum scst_exec_res res; TRACE_ENTRY(); @@ -2742,9 +2742,9 @@ static int scst_maintenance_in(struct scst_cmd *cmd) return res; } -static int scst_reserve_local(struct scst_cmd *cmd) +static enum scst_exec_res scst_reserve_local(struct scst_cmd *cmd) { - int res = SCST_EXEC_NOT_COMPLETED; + enum scst_exec_res res = SCST_EXEC_NOT_COMPLETED; struct scst_device *dev; struct scst_lksb pr_lksb; @@ -2818,9 +2818,9 @@ out_done: goto out; } -static int scst_release_local(struct scst_cmd *cmd) +static enum scst_exec_res scst_release_local(struct scst_cmd *cmd) { - int res = SCST_EXEC_NOT_COMPLETED; + enum scst_exec_res res = SCST_EXEC_NOT_COMPLETED; struct scst_device *dev; struct scst_lksb pr_lksb; @@ -2894,7 +2894,7 @@ out_done: } /* No locks, no IRQ or IRQ-disabled context allowed */ -static int scst_persistent_reserve_in_local(struct scst_cmd *cmd) +static enum scst_exec_res scst_persistent_reserve_in_local(struct scst_cmd *cmd) { struct scst_device *dev; struct scst_tgt_dev *tgt_dev; @@ -3002,9 +3002,10 @@ out_unsup_act: } /* No locks, no IRQ or IRQ-disabled context allowed */ -static int scst_persistent_reserve_out_local(struct scst_cmd *cmd) +static enum scst_exec_res +scst_persistent_reserve_out_local(struct scst_cmd *cmd) { - int res = SCST_EXEC_COMPLETED; + enum scst_exec_res res = SCST_EXEC_COMPLETED; struct scst_device *dev; struct scst_tgt_dev *tgt_dev; struct scst_session *session; @@ -3401,9 +3402,9 @@ out: } /* cmd must be additionally referenced to not die inside */ -static int scst_do_real_exec(struct scst_cmd *cmd) +static enum scst_exec_res scst_do_real_exec(struct scst_cmd *cmd) { - int res = SCST_EXEC_NOT_COMPLETED; + enum scst_exec_res res = SCST_EXEC_NOT_COMPLETED; int rc; struct scst_device *dev = cmd->dev; struct scst_dev_type *devt = cmd->devt; @@ -3523,7 +3524,7 @@ out_done: goto out; } -typedef int (*scst_local_exec_fn)(struct scst_cmd *cmd); +typedef enum scst_exec_res (*scst_local_exec_fn)(struct scst_cmd *cmd); static scst_local_exec_fn scst_local_fns[256] = { [RESERVE] = scst_reserve_local, @@ -3540,9 +3541,9 @@ static scst_local_exec_fn scst_local_fns[256] = { [MAINTENANCE_IN] = scst_maintenance_in, }; -static int scst_do_local_exec(struct scst_cmd *cmd) +static enum scst_exec_res scst_do_local_exec(struct scst_cmd *cmd) { - int res; + enum scst_exec_res res; struct scst_tgt_dev *tgt_dev = cmd->tgt_dev; TRACE_ENTRY(); @@ -3577,9 +3578,10 @@ out_done: goto out; } -static int scst_local_exec(struct scst_cmd *cmd) +static enum scst_exec_res scst_local_exec(struct scst_cmd *cmd) { - int res, rc; + enum scst_exec_res res; + int rc; TRACE_ENTRY(); From 34f9b158e236c63e7748477608d7581554b510a7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Feb 2019 03:16:12 +0000 Subject: [PATCH 5/5] scst: Only switch to thread context if no Data-Out buffer and no failure This patch avoids that the following is reported: [0]: scst_pre_parse:949:Failed CDB: (h)___0__1__2__3__4__5__6__7__8__9__A__B__C__D__E__F 0: 8b 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 ................ [0]: dev_vdisk: vdisk_parse_offset:2999:Unknown opcode 0x8b [0]: scst_parse_cmd:1333:Atomic context and non-WRITE data direction, rescheduling (cmd 00000000cd981f2b) [0]: scst: scst_process_active_cmd:5571:***CRITICAL ERROR***: cmd 00000000cd981f2b is in invalid state 10) BUG at /home/bart/software/scst.git/scst/src/scst_targ.c:5572 ------------[ cut here ]------------ DEBUG_LOCKS_WARN_ON(val > preempt_count()) WARNING: CPU: 1 PID: 0 at kernel/sched/core.c:3230 preempt_count_sub+0x7f/0xd0 Modules linked in: qla2x00tgt(O) scst_vdisk(O) isert_scst(O) iscsi_scst(O) scst(O) sd_mod sg brd dlm af_packet crct10dif_pclmul hid_generic aesni_intel aes_x86_64 crypto_simd cryptd usbhid glue_helper hid qla2xxx_scst(O) virtio_balloon l CPU: 1 PID: 0 Comm: swapper/1 Tainted: G W O 5.0.0-rc6-dbg+ #2 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 Call Trace: __local_bh_enable_ip+0x7e/0x140 local_bh_enable+0x15/0x20 [scst] scst_process_active_cmd+0x555/0x570 [scst] scst_do_job_active.constprop.23+0x57/0xe0 [scst] scst_cmd_tasklet+0x42/0x70 [scst] tasklet_action_common.isra.14+0xc3/0x280 tasklet_action+0x3d/0x50 __do_softirq+0x12d/0x5b7 irq_exit+0xdd/0x100 do_IRQ+0xc3/0x160 common_interrupt+0xf/0xf git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7922 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_targ.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 628239d98..617cc3cbb 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -1327,7 +1327,7 @@ set_res: * be because of the SCST_TGT_DEV_AFTER_* optimization, but during * parsing data_direction can change, so we need to recheck. */ - if (unlikely(scst_cmd_atomic(cmd) && + if (unlikely(scst_cmd_atomic(cmd) && cmd->status == 0 && !(cmd->data_direction & SCST_DATA_WRITE))) { TRACE_DBG_FLAG(TRACE_DEBUG|TRACE_MINOR, "Atomic context and " "non-WRITE data direction, rescheduling (cmd %p)", cmd);