From patchwork Sun Jul 23 23:40:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323133 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EBEE7C001DE for ; Sun, 23 Jul 2023 10:19:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229768AbjGWKT4 (ORCPT ); Sun, 23 Jul 2023 06:19:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229677AbjGWKTz (ORCPT ); Sun, 23 Jul 2023 06:19:55 -0400 Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 386C9E6; Sun, 23 Jul 2023 03:19:54 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.55]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4R7zm704KZz18Lbg; Sun, 23 Jul 2023 18:19:02 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:51 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 1/9] scsi:scsi_debug: create scsi_debug directory in the debugfs filesystem Date: Mon, 24 Jul 2023 07:40:57 +0800 Message-ID: <20230723234105.1628982-2-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Create directory scsi_debug in the root of the debugfs filesystem. Prepare to add interface for manage error injection. Signed-off-by: Wenchao Hao Acked-by: Douglas Gilbert --- drivers/scsi/scsi_debug.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9c0af50501f9..35c336271b13 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -862,6 +863,8 @@ static const int device_qfull_result = static const int condition_met_result = SAM_STAT_CONDITION_MET; +static struct dentry *sdebug_debugfs_root; + /* Only do the extra work involved in logical block provisioning if one or * more of the lbpu, lbpws or lbpws10 parameters are given and we are doing @@ -7011,6 +7014,8 @@ static int __init scsi_debug_init(void) goto driver_unreg; } + sdebug_debugfs_root = debugfs_create_dir("scsi_debug", NULL); + for (k = 0; k < hosts_to_add; k++) { if (want_store && k == 0) { ret = sdebug_add_host_helper(idx); @@ -7057,6 +7062,7 @@ static void __exit scsi_debug_exit(void) sdebug_erase_all_stores(false); xa_destroy(per_store_ap); + debugfs_remove(sdebug_debugfs_root); } device_initcall(scsi_debug_init); From patchwork Sun Jul 23 23:40:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323135 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5525C04A6A for ; Sun, 23 Jul 2023 10:19:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229677AbjGWKT6 (ORCPT ); Sun, 23 Jul 2023 06:19:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229732AbjGWKT4 (ORCPT ); Sun, 23 Jul 2023 06:19:56 -0400 Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 62B73100; Sun, 23 Jul 2023 03:19:54 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.55]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4R7zm74qj3z18LcT; Sun, 23 Jul 2023 18:19:03 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:51 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 2/9] scsi:scsi_debug: Add interface to manage single device's error inject Date: Mon, 24 Jul 2023 07:40:58 +0800 Message-ID: <20230723234105.1628982-3-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org This new facility uses the debugfs pseudo file system which is typically mounted under the /sys/kernel/debug directory and requires root permissions to access. The interface file is found at /sys/kernel/debug/scsi_debug//error where identifies the device (logical unit (LU)) to inject errors on. For the following description the ${error} environment variable is assumed to be set to/sys/kernel/debug/scsi_debug/1:0:0:0/error where 1:0:0:0 is a pseudo device (LU) owned by the scsi_debug driver. Rules are written to ${error} in the normal sysfs fashion (e.g. 'echo "0 -2 0x12" > ${error}'). More than one rule can be active on a device at a time and inactive rules (i.e. those whose Error count is 0) remain in the rule listing. The existing rules can be read with 'cat ${error}' with one line output for each rule. The interface format is line-by-line, each line is an error injection rule. Each rule contains integers separated by spaces, the first three columns correspond to "Error code", "Error count" and "SCSI command", other columns depend on Error code. General rule format: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error code | | | | 0: timeout SCSI command | | | | 1: fail queuecommand, make queuecommand return | | | | given value | | | | 2: fail command, finish command with SCSI status, | | | | sense key and ASC/ASCQ values | | | | 3: make abort commands for specific command fail | | | | 4: make reset lun for specific command fail | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error count | | | | 0: this rule will be ignored | | | | positive: the rule will always take effect | | | | negative: the rule takes effect n times where -n is | | | | the value given. Ignored after n times | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command opcode, 0xff for all commands | +--------+------+-------------------------------------------------------+ | ... | xxx | Error type specific fields | +--------+------+-------------------------------------------------------+ Notes: - when multiple error inject rules are added for the same SCSI command, the one with smaller error code will take effect (and the others will be ignored). - if an same error (i.e. same Error code and SCSI command) is added, the older one will be overwritten. - Currently, the basic types are (u8/u16/u32/u64/s8/s16/s32/s64) and the hexadecimal types (x8/x16/x32/x64) - where a hexadecimal value is expected (e.g. Column 3: SCSI command opcode) the "0x" prefix is optional on the value (e.g. the INQUIRY opcode can be given as '0x12' or '12') - when the Error count is negative, reading ${error} will show that value incrementing, stopping when it gets to 0 Signed-off-by: Wenchao Hao Acked-by: Douglas Gilbert --- V3: - cut and paste description about the error injection from: https://doug-gilbert.github.io/scsi_debug.html - Fix possible NULL point access in scsi_debug_slave_destroy - Do not describe all error types' format in detail - Free errors added to devices' list to fix memleak when rmmod scsi_debug without clear these error info - Fix memkeak because did not implement release in sdebug_error_fops - Fix possible NULL point access in scsi_debug_slave_destroy reported by Dan Carpenter drivers/scsi/scsi_debug.c | 191 +++++++++++++++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 35c336271b13..d7d0c8af8bff 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -286,6 +286,41 @@ struct sdeb_zone_state { /* ZBC: per zone state */ sector_t z_wp; }; +enum sdebug_err_type { + ERR_TMOUT_CMD = 0, /* make specific scsi command timeout */ + ERR_FAIL_QUEUE_CMD = 1, /* make specific scsi command's */ + /* queuecmd return failed */ + ERR_FAIL_CMD = 2, /* make specific scsi command's */ + /* queuecmd return succeed but */ + /* with errors set in scsi_cmnd */ +}; + +struct sdebug_err_inject { + int type; + struct list_head list; + int cnt; + unsigned char cmd; + + union { + /* + * For ERR_FAIL_QUEUE_CMD + */ + int queuecmd_ret; + + /* + * For ERR_FAIL_CMD + */ + struct { + unsigned char host_byte; + unsigned char driver_byte; + unsigned char status_byte; + unsigned char sense_key; + unsigned char asc; + unsigned char asq; + }; + }; +}; + struct sdebug_dev_info { struct list_head dev_list; unsigned int channel; @@ -311,6 +346,9 @@ struct sdebug_dev_info { unsigned int max_open; ktime_t create_ts; /* time since bootup that this device was created */ struct sdeb_zone_state *zstate; + + struct dentry *debugfs_entry; + struct list_head inject_err_list; }; struct sdebug_host_info { @@ -865,6 +903,133 @@ static const int condition_met_result = SAM_STAT_CONDITION_MET; static struct dentry *sdebug_debugfs_root; +static void sdebug_err_add(struct scsi_device *sdev, struct sdebug_err_inject *new) +{ + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdev->hostdata; + struct sdebug_err_inject *tmp, *err; + + list_for_each_entry_safe(err, tmp, &devip->inject_err_list, list) { + if (err->type == new->type && err->cmd == new->cmd) { + sdev_printk(KERN_INFO, sdev, "Substituted %d 0x%x\n", + err->type, err->cmd); + list_del(&err->list); + kfree(err); + } + } + + list_add_tail(&new->list, &devip->inject_err_list); +} + +static int sdebug_error_show(struct seq_file *m, void *p) +{ + struct scsi_device *sdev = (struct scsi_device *)m->private; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdev->hostdata; + struct sdebug_err_inject *err; + + seq_puts(m, "Type\tCount\tCommand\n"); + + list_for_each_entry(err, &devip->inject_err_list, list) { + switch (err->type) { + case ERR_TMOUT_CMD: + seq_printf(m, "%d\t%d\t0x%x\n", err->type, err->cnt, + err->cmd); + break; + + case ERR_FAIL_QUEUE_CMD: + seq_printf(m, "%d\t%d\t0x%x\t0x%x\n", err->type, + err->cnt, err->cmd, err->queuecmd_ret); + break; + + case ERR_FAIL_CMD: + seq_printf(m, "%d\t%d\t0x%x\t0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + err->type, err->cnt, err->cmd, + err->host_byte, err->driver_byte, + err->status_byte, err->sense_key, + err->asc, err->asq); + break; + } + } + + return 0; +} + +static int sdebug_error_open(struct inode *inode, struct file *file) +{ + return single_open(file, sdebug_error_show, inode->i_private); +} + +static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + char *buf; + unsigned int inject_type; + struct sdebug_err_inject *inject; + struct scsi_device *sdev = (struct scsi_device *)file->f_inode->i_private; + + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, ubuf, count)) { + kfree(buf); + return -EFAULT; + } + + if (sscanf(buf, "%d", &inject_type) != 1) { + kfree(buf); + return -EINVAL; + } + + inject = kzalloc(sizeof(struct sdebug_err_inject), GFP_KERNEL); + if (!inject) { + kfree(buf); + return -ENOMEM; + } + + switch (inject_type) { + case ERR_TMOUT_CMD: + if (sscanf(buf, "%d %d %hhx", &inject->type, &inject->cnt, + &inject->cmd) != 3) + goto out_error; + break; + + case ERR_FAIL_QUEUE_CMD: + if (sscanf(buf, "%d %d %hhx %x", &inject->type, &inject->cnt, + &inject->cmd, &inject->queuecmd_ret) != 4) + goto out_error; + break; + + case ERR_FAIL_CMD: + if (sscanf(buf, "%d %d %hhx %hhx %hhx %hhx %hhx %hhx %hhx", + &inject->type, &inject->cnt, &inject->cmd, + &inject->host_byte, &inject->driver_byte, + &inject->status_byte, &inject->sense_key, + &inject->asc, &inject->asq) != 9) + goto out_error; + break; + + default: + goto out_error; + break; + } + + kfree(buf); + sdebug_err_add(sdev, inject); + + return count; + +out_error: + kfree(buf); + kfree(inject); + return -EINVAL; +} + +static const struct file_operations sdebug_error_fops = { + .open = sdebug_error_open, + .read = seq_read, + .write = sdebug_error_write, + .release = single_release, +}; /* Only do the extra work involved in logical block provisioning if one or * more of the lbpu, lbpws or lbpws10 parameters are given and we are doing @@ -5099,6 +5264,7 @@ static struct sdebug_dev_info *sdebug_device_create( } devip->create_ts = ktime_get_boottime(); atomic_set(&devip->stopped, (sdeb_tur_ms_to_ready > 0 ? 2 : 0)); + INIT_LIST_HEAD(&devip->inject_err_list); list_add_tail(&devip->dev_list, &sdbg_host->dev_info_list); } return devip; @@ -5144,6 +5310,7 @@ static int scsi_debug_slave_alloc(struct scsi_device *sdp) if (sdebug_verbose) pr_info("slave_alloc <%u %u %u %llu>\n", sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); + return 0; } @@ -5166,6 +5333,12 @@ static int scsi_debug_slave_configure(struct scsi_device *sdp) if (sdebug_no_uld) sdp->no_uld_attach = 1; config_cdb_len(sdp); + + devip->debugfs_entry = debugfs_create_dir(dev_name(&sdp->sdev_dev), + sdebug_debugfs_root); + debugfs_create_file("error", 0600, devip->debugfs_entry, sdp, + &sdebug_error_fops); + return 0; } @@ -5173,15 +5346,25 @@ static void scsi_debug_slave_destroy(struct scsi_device *sdp) { struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *tmp, *err; if (sdebug_verbose) pr_info("slave_destroy <%u %u %u %llu>\n", sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); - if (devip) { - /* make this slot available for re-use */ - devip->used = false; - sdp->hostdata = NULL; + + if (!devip) + return; + + list_for_each_entry_safe(err, tmp, &devip->inject_err_list, list) { + list_del(&err->list); + kfree(err); } + + debugfs_remove(devip->debugfs_entry); + + /* make this slot available for re-use */ + devip->used = false; + sdp->hostdata = NULL; } /* Returns true if we require the queued memory to be freed by the caller. */ From patchwork Sun Jul 23 23:40:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323137 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62D08C04A6A for ; Sun, 23 Jul 2023 10:20:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230006AbjGWKUC (ORCPT ); Sun, 23 Jul 2023 06:20:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229865AbjGWKT5 (ORCPT ); Sun, 23 Jul 2023 06:19:57 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7689E6; Sun, 23 Jul 2023 03:19:55 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.53]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4R7zjQ1TprztRFL; Sun, 23 Jul 2023 18:16:42 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:52 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 3/9] scsi:scsi_debug: Define grammar to remove added error injection Date: Mon, 24 Jul 2023 07:40:59 +0800 Message-ID: <20230723234105.1628982-4-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The grammar to remove error injection is a line with fixed 3 columns separated by spaces. First column is fixed to "-". It tells this is a removal operation. Second column is the error code to match. Third column is the scsi command to match. For example the following command would remove timeout injection of inquiry command. echo "- 0 0x12" > /sys/kernel/debug/scsi_debug/0:0:0:1/error Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d7d0c8af8bff..c83bd1e52622 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -920,6 +920,33 @@ static void sdebug_err_add(struct scsi_device *sdev, struct sdebug_err_inject *n list_add_tail(&new->list, &devip->inject_err_list); } +static int sdebug_err_remove(struct scsi_device *sdev, const char *buf, size_t count) +{ + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdev->hostdata; + struct sdebug_err_inject *tmp, *err; + int type; + unsigned char cmd; + + if (sscanf(buf, "- %d %hhx", &type, &cmd) != 2) { + kfree(buf); + return -EINVAL; + } + + list_for_each_entry_safe(err, tmp, &devip->inject_err_list, list) { + if (err->type == type && err->cmd == cmd) { + sdev_printk(KERN_INFO, sdev, "Remove %d 0x%x\n", + err->type, err->cmd); + list_del(&err->list); + kfree(err); + kfree(buf); + return count; + } + } + + kfree(buf); + return -EINVAL; +} + static int sdebug_error_show(struct seq_file *m, void *p) { struct scsi_device *sdev = (struct scsi_device *)m->private; @@ -975,6 +1002,9 @@ static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf, return -EFAULT; } + if (buf[0] == '-') + return sdebug_err_remove(sdev, buf, count); + if (sscanf(buf, "%d", &inject_type) != 1) { kfree(buf); return -EINVAL; From patchwork Sun Jul 23 23:41:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323136 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 865D1C001DE for ; Sun, 23 Jul 2023 10:20:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229980AbjGWKUA (ORCPT ); Sun, 23 Jul 2023 06:20:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229841AbjGWKT5 (ORCPT ); Sun, 23 Jul 2023 06:19:57 -0400 Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E594138; Sun, 23 Jul 2023 03:19:55 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.55]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4R7zm90231z18LcW; Sun, 23 Jul 2023 18:19:04 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:53 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 4/9] scsi:scsi_debug: timeout command if the error is injected Date: Mon, 24 Jul 2023 07:41:00 +0800 Message-ID: <20230723234105.1628982-5-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org If a timeout error is injected, return 0 from scsi_debug_queuecommand to make the command timeout. Timeout SCSI command format: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x0 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error count | | | | 0: this rule will be ignored | | | | positive: the rule will always take effect | | | | negative: the rule takes effect n times where -n is | | | | the value given. Ignored after n times | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command opcode, 0xff for all commands | +--------+------+-------------------------------------------------------+ Examples: error=/sys/kernel/debug/scsi_debug/0:0:0:1/error echo "0 -10 0x12" > ${error} will make the device's inquiry command timeout 10 times. echo "0 1 0x12" > ${error} will make the device's inquiry timeout each time it is invoked on this device. Signed-off-by: Wenchao Hao Acked-by: Douglas Gilbert --- drivers/scsi/scsi_debug.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index c83bd1e52622..107577bac65d 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7715,6 +7715,30 @@ static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) return num_entries; } +static int sdebug_timeout_cmd(struct scsi_cmnd *cmnd) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_TMOUT_CMD && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + ret = !!err->cnt; + if (err->cnt < 0) + err->cnt++; + return ret; + } + } + + return 0; +} + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7773,6 +7797,12 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, if (NULL == devip) goto err_out; } + + if (sdebug_timeout_cmd(scp)) { + scmd_printk(KERN_INFO, scp, "timeout command 0x%x\n", opcode); + return 0; + } + if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending))) atomic_set(&sdeb_inject_pending, 1); From patchwork Sun Jul 23 23:41:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323138 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7894AC001DC for ; Sun, 23 Jul 2023 10:20:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230013AbjGWKUE (ORCPT ); Sun, 23 Jul 2023 06:20:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49480 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229881AbjGWKT6 (ORCPT ); Sun, 23 Jul 2023 06:19:58 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A1E8A100; Sun, 23 Jul 2023 03:19:56 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.57]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4R7zjR3nSbztQr4; Sun, 23 Jul 2023 18:16:43 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:53 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 5/9] scsi:scsi_debug: Return failed value if the error is injected Date: Mon, 24 Jul 2023 07:41:01 +0800 Message-ID: <20230723234105.1628982-6-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org If a fail queuecommand error is injected, return the failed value defined in the rule from queuecommand. Make queuecommand return format: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x1 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error count | | | | 0: this rule will be ignored | | | | positive: the rule will always take effect | | | | negative: the rule takes effect n times where -n is | | | | the value given. Ignored after n times | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command opcode, 0xff for all commands | +--------+------+-------------------------------------------------------+ | 4 | x32 | The queuecommand() return value we want | +--------+------+-------------------------------------------------------+ Examples: error=/sys/kernel/debug/scsi_debug/0:0:0:1/error echo "1 1 0x12 0x1055" > ${error} will make each INQUIRY command sent to that device return 0x1055 (SCSI_MLQUEUE_HOST_BUSY). Signed-off-by: Wenchao Hao Acked-by: Douglas Gilbert --- drivers/scsi/scsi_debug.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 107577bac65d..1d28e7209f64 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7739,6 +7739,30 @@ static int sdebug_timeout_cmd(struct scsi_cmnd *cmnd) return 0; } +static int sdebug_fail_queue_cmd(struct scsi_cmnd *cmnd) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_FAIL_QUEUE_CMD && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + ret = err->cnt ? err->queuecmd_ret : 0; + if (err->cnt < 0) + err->cnt++; + return ret; + } + } + + return 0; +} + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7758,6 +7782,7 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, u8 opcode = cmd[0]; bool has_wlun_rl; bool inject_now; + int ret = 0; scsi_set_resid(scp, 0); if (sdebug_statistics) { @@ -7803,6 +7828,13 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, return 0; } + ret = sdebug_fail_queue_cmd(scp); + if (ret) { + scmd_printk(KERN_INFO, scp, "fail queue command 0x%x with 0x%x\n", + opcode, ret); + return ret; + } + if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending))) atomic_set(&sdeb_inject_pending, 1); From patchwork Sun Jul 23 23:41:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323139 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6B5CC001DE for ; Sun, 23 Jul 2023 10:20:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230021AbjGWKUG (ORCPT ); Sun, 23 Jul 2023 06:20:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49486 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229907AbjGWKT6 (ORCPT ); Sun, 23 Jul 2023 06:19:58 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B23212F; Sun, 23 Jul 2023 03:19:57 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.57]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4R7zm946mszrRpb; Sun, 23 Jul 2023 18:19:05 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:54 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 6/9] scsi:scsi_debug: set command's result and sense data if the error is injected Date: Mon, 24 Jul 2023 07:41:02 +0800 Message-ID: <20230723234105.1628982-7-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org If a fail commnd error is injected, set the command's status and sense data then finish this scsi command. Set SCSI command's status and sense data format: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x2 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error Count | | | | 0: the rule will be ignored | | | | positive: the rule will always take effect | | | | negative: the rule takes effect n times where -n is | | | | the value given. Ignored after n times | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command opcode, 0xff for all commands | +--------+------+-------------------------------------------------------+ | 4 | x8 | Host byte in scsi_cmd::status | | | | [scsi_cmd::status has 32 bits holding these 3 bytes] | +--------+------+-------------------------------------------------------+ | 5 | x8 | Driver byte in scsi_cmd::status | +--------+------+-------------------------------------------------------+ | 6 | x8 | SCSI Status byte in scsi_cmd::status | +--------+------+-------------------------------------------------------+ | 7 | x8 | SCSI Sense Key in scsi_cmnd | +--------+------+-------------------------------------------------------+ | 8 | x8 | SCSI ASC in scsi_cmnd | +--------+------+-------------------------------------------------------+ | 9 | x8 | SCSI ASCQ in scsi_cmnd | +--------+------+-------------------------------------------------------+ Examples: error=/sys/kernel/debug/scsi_debug/0:0:0:1/error echo "2 -10 0x88 0 0 0x2 0x3 0x11 0x0" >${error} will make device's read command return with media error with additional sense of "Unrecovered read error" (UNC): Signed-off-by: Wenchao Hao Acked-by: Douglas Gilbert --- drivers/scsi/scsi_debug.c | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 1d28e7209f64..94c43b800694 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7763,6 +7763,41 @@ static int sdebug_fail_queue_cmd(struct scsi_cmnd *cmnd) return 0; } +static int sdebug_fail_cmd(struct scsi_cmnd *cmnd, int *retval, + struct sdebug_err_inject *info) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + int result; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_FAIL_CMD && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + if (!err->cnt) + return 0; + ret = !!err->cnt; + goto out_handle; + } + } + return 0; + +out_handle: + if (err->cnt < 0) + err->cnt++; + mk_sense_buffer(cmnd, err->sense_key, err->asc, err->asq); + result = err->status_byte | err->host_byte << 16 | err->driver_byte << 24; + *info = *err; + *retval = schedule_resp(cmnd, devip, result, NULL, 0, 0); + + return ret; +} + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7783,6 +7818,7 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, bool has_wlun_rl; bool inject_now; int ret = 0; + struct sdebug_err_inject err; scsi_set_resid(scp, 0); if (sdebug_statistics) { @@ -7835,6 +7871,16 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, return ret; } + if (sdebug_fail_cmd(scp, &ret, &err)) { + scmd_printk(KERN_INFO, scp, + "fail command 0x%x with hostbyte=0x%x, " + "driverbyte=0x%x, statusbyte=0x%x, " + "sense_key=0x%x, asc=0x%x, asq=0x%x\n", + opcode, err.host_byte, err.driver_byte, + err.status_byte, err.sense_key, err.asc, err.asq); + return ret; + } + if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending))) atomic_set(&sdeb_inject_pending, 1); From patchwork Sun Jul 23 23:41:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323141 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0E94C001DF for ; Sun, 23 Jul 2023 10:20:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230015AbjGWKUT (ORCPT ); Sun, 23 Jul 2023 06:20:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229976AbjGWKT7 (ORCPT ); Sun, 23 Jul 2023 06:19:59 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 207C4E52; Sun, 23 Jul 2023 03:19:58 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.54]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4R7zjS6C43ztR4c; Sun, 23 Jul 2023 18:16:44 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:55 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 7/9] scsi:scsi_debug: Add new error injection abort failed Date: Mon, 24 Jul 2023 07:41:03 +0800 Message-ID: <20230723234105.1628982-8-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Add error injection type 3 to make scsi_debug_abort() return FAILED. Fail abort command foramt: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x3 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error count | | | | 0: this rule will be ignored | | | | positive: the rule will always take effect | | | | negative: the rule takes effect n times where -n is | | | | the value given. Ignored after n times | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command opcode, 0xff for all commands | +--------+------+-------------------------------------------------------+ Examples: error=/sys/kernel/debug/scsi_debug/0:0:0:1/error echo "0 -10 0x12" > ${error} will make the device return FAILED when abort inquiry command 10 times. Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 94c43b800694..9e4ea3b38cd0 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -293,6 +293,8 @@ enum sdebug_err_type { ERR_FAIL_CMD = 2, /* make specific scsi command's */ /* queuecmd return succeed but */ /* with errors set in scsi_cmnd */ + ERR_ABORT_CMD_FAILED = 3, /* control return FAILED from */ + /* scsi_debug_abort() */ }; struct sdebug_err_inject { @@ -958,6 +960,7 @@ static int sdebug_error_show(struct seq_file *m, void *p) list_for_each_entry(err, &devip->inject_err_list, list) { switch (err->type) { case ERR_TMOUT_CMD: + case ERR_ABORT_CMD_FAILED: seq_printf(m, "%d\t%d\t0x%x\n", err->type, err->cnt, err->cmd); break; @@ -1018,6 +1021,7 @@ static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf, switch (inject_type) { case ERR_TMOUT_CMD: + case ERR_ABORT_CMD_FAILED: if (sscanf(buf, "%d %d %hhx", &inject->type, &inject->cnt, &inject->cmd) != 3) goto out_error; @@ -5488,9 +5492,35 @@ static void stop_all_queued(void) mutex_unlock(&sdebug_host_list_mutex); } +static int sdebug_fail_abort(struct scsi_cmnd *cmnd) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_ABORT_CMD_FAILED && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + ret = !!err->cnt; + if (err->cnt < 0) + err->cnt++; + return ret; + } + } + + return 0; +} + static int scsi_debug_abort(struct scsi_cmnd *SCpnt) { bool ok = scsi_debug_abort_cmnd(SCpnt); + u8 *cmd = SCpnt->cmnd; + u8 opcode = cmd[0]; ++num_aborts; @@ -5499,6 +5529,12 @@ static int scsi_debug_abort(struct scsi_cmnd *SCpnt) "%s: command%s found\n", __func__, ok ? "" : " not"); + if (sdebug_fail_abort(SCpnt)) { + scmd_printk(KERN_INFO, SCpnt, "fail abort command 0x%x\n", + opcode); + return FAILED; + } + return SUCCESS; } From patchwork Sun Jul 23 23:41:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323140 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90B37C001DC for ; Sun, 23 Jul 2023 10:20:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230053AbjGWKUR (ORCPT ); Sun, 23 Jul 2023 06:20:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229977AbjGWKUA (ORCPT ); Sun, 23 Jul 2023 06:20:00 -0400 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BBD8C138; Sun, 23 Jul 2023 03:19:58 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.56]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4R7zlR0Jf6zVjXj; Sun, 23 Jul 2023 18:18:27 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:55 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 8/9] scsi:scsi_debug: Add new error injection reset lun failed Date: Mon, 24 Jul 2023 07:41:04 +0800 Message-ID: <20230723234105.1628982-9-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Add error injection type 3 to make scsi_debug_device_reset() return FAILED. Fail abort command foramt: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x4 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error count | | | | 0: this rule will be ignored | | | | positive: the rule will always take effect | | | | negative: the rule takes effect n times where -n is | | | | the value given. Ignored after n times | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command opcode, 0xff for all commands | +--------+------+-------------------------------------------------------+ Examples: error=/sys/kernel/debug/scsi_debug/0:0:0:1/error echo "0 -10 0x12" > ${error} will make the device return FAILED when try to reset lun with inquiry command 10 times. error=/sys/kernel/debug/scsi_debug/0:0:0:1/error echo "0 -10 0xff" > ${error} will make the device return FAILED when try to reset lun 10 times. Usually we do not care about what command it is when trying to perform reset LUN, so 0xff could be applied. Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9e4ea3b38cd0..2c16e5f4ab28 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -295,6 +295,8 @@ enum sdebug_err_type { /* with errors set in scsi_cmnd */ ERR_ABORT_CMD_FAILED = 3, /* control return FAILED from */ /* scsi_debug_abort() */ + ERR_LUN_RESET_FAILED = 4, /* control return FAILED from */ + /* scsi_debug_device_reseLUN_RESET_FAILEDt() */ }; struct sdebug_err_inject { @@ -961,6 +963,7 @@ static int sdebug_error_show(struct seq_file *m, void *p) switch (err->type) { case ERR_TMOUT_CMD: case ERR_ABORT_CMD_FAILED: + case ERR_LUN_RESET_FAILED: seq_printf(m, "%d\t%d\t0x%x\n", err->type, err->cnt, err->cmd); break; @@ -1022,6 +1025,7 @@ static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf, switch (inject_type) { case ERR_TMOUT_CMD: case ERR_ABORT_CMD_FAILED: + case ERR_LUN_RESET_FAILED: if (sscanf(buf, "%d %d %hhx", &inject->type, &inject->cnt, &inject->cmd) != 3) goto out_error; @@ -5558,10 +5562,36 @@ static void scsi_debug_stop_all_queued(struct scsi_device *sdp) scsi_debug_stop_all_queued_iter, sdp); } +static int sdebug_fail_lun_reset(struct scsi_cmnd *cmnd) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_LUN_RESET_FAILED && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + ret = !!err->cnt; + if (err->cnt < 0) + err->cnt++; + return ret; + } + } + + return 0; +} + static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt) { struct scsi_device *sdp = SCpnt->device; struct sdebug_dev_info *devip = sdp->hostdata; + u8 *cmd = SCpnt->cmnd; + u8 opcode = cmd[0]; ++num_dev_resets; @@ -5572,6 +5602,11 @@ static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt) if (devip) set_bit(SDEBUG_UA_POR, devip->uas_bm); + if (sdebug_fail_lun_reset(SCpnt)) { + scmd_printk(KERN_INFO, SCpnt, "fail lun reset 0x%x\n", opcode); + return FAILED; + } + return SUCCESS; } From patchwork Sun Jul 23 23:41:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenchao Hao X-Patchwork-Id: 13323142 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71970C001DC for ; Sun, 23 Jul 2023 10:20:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229881AbjGWKUV (ORCPT ); Sun, 23 Jul 2023 06:20:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229983AbjGWKUA (ORCPT ); Sun, 23 Jul 2023 06:20:00 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21F24E76; Sun, 23 Jul 2023 03:19:59 -0700 (PDT) Received: from kwepemm600012.china.huawei.com (unknown [172.30.72.53]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4R7zjV1KrFztR79; Sun, 23 Jul 2023 18:16:46 +0800 (CST) Received: from build.huawei.com (10.175.101.6) by kwepemm600012.china.huawei.com (7.193.23.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sun, 23 Jul 2023 18:19:56 +0800 From: Wenchao Hao To: "James E . J . Bottomley" , "Martin K . Petersen" , Douglas Gilbert , , CC: Dan Carpenter , , Wenchao Hao Subject: [PATCH v3 9/9] scsi:scsi_debug: Add debugfs interface to fail target reset Date: Mon, 24 Jul 2023 07:41:05 +0800 Message-ID: <20230723234105.1628982-10-haowenchao2@huawei.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20230723234105.1628982-1-haowenchao2@huawei.com> References: <20230723234105.1628982-1-haowenchao2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.101.6] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm600012.china.huawei.com (7.193.23.74) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The interface is found at /sys/kernel/debug/scsi_debug/target/fail_reset where identifies the target to inject errors on. It's a simple bool type interface which would make this target's reset fail if set to 'Y'. Signed-off-by: Wenchao Hao --- drivers/scsi/scsi_debug.c | 97 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 2c16e5f4ab28..2c5ed618f228 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -355,6 +355,11 @@ struct sdebug_dev_info { struct list_head inject_err_list; }; +struct sdebug_target_info { + bool reset_fail; + struct dentry *debugfs_entry; +}; + struct sdebug_host_info { struct list_head host_list; int si_idx; /* sdeb_store_info (per host) xarray index */ @@ -1069,6 +1074,75 @@ static const struct file_operations sdebug_error_fops = { .release = single_release, }; +static int sdebug_target_reset_fail_show(struct seq_file *m, void *p) +{ + struct scsi_target *starget = (struct scsi_target *)m->private; + struct sdebug_target_info *targetip = + (struct sdebug_target_info *)starget->hostdata; + + if (targetip) + seq_printf(m, "%c\n", targetip->reset_fail ? 'Y' : 'N'); + + return 0; +} + +static int sdebug_target_reset_fail_open(struct inode *inode, struct file *file) +{ + return single_open(file, sdebug_target_reset_fail_show, inode->i_private); +} + +static ssize_t sdebug_target_reset_fail_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + int ret; + struct scsi_target *starget = + (struct scsi_target *)file->f_inode->i_private; + struct sdebug_target_info *targetip = + (struct sdebug_target_info *)starget->hostdata; + + if (targetip) { + ret = kstrtobool_from_user(ubuf, count, &targetip->reset_fail); + return ret < 0 ? ret : count; + } + return -ENODEV; +} + +static const struct file_operations sdebug_target_reset_fail_fops = { + .open = sdebug_target_reset_fail_open, + .read = seq_read, + .write = sdebug_target_reset_fail_write, + .release = single_release, +}; + +static int sdebug_target_alloc(struct scsi_target *starget) +{ + struct sdebug_target_info *targetip; + + targetip = kzalloc(sizeof(struct sdebug_target_info), GFP_KERNEL); + if (!targetip) + return -ENOMEM; + + targetip->debugfs_entry = debugfs_create_dir(dev_name(&starget->dev), + sdebug_debugfs_root); + debugfs_create_file("fail_reset", 0600, targetip->debugfs_entry, starget, + &sdebug_target_reset_fail_fops); + + starget->hostdata = targetip; + + return 0; +} + +static void sdebug_target_destroy(struct scsi_target *starget) +{ + struct sdebug_target_info *targetip; + + targetip = (struct sdebug_target_info *)starget->hostdata; + if (targetip) { + debugfs_remove(targetip->debugfs_entry); + kfree(targetip); + } +} + /* Only do the extra work involved in logical block provisioning if one or * more of the lbpu, lbpws or lbpws10 parameters are given and we are doing * real reads and writes (i.e. not skipping them for speed). @@ -5610,11 +5684,25 @@ static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt) return SUCCESS; } +static int sdebug_fail_target_reset(struct scsi_cmnd *cmnd) +{ + struct scsi_target *starget = scsi_target(cmnd->device); + struct sdebug_target_info *targetip = + (struct sdebug_target_info *)starget->hostdata; + + if (targetip) + return targetip->reset_fail; + + return 0; +} + static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt) { struct scsi_device *sdp = SCpnt->device; struct sdebug_host_info *sdbg_host = shost_to_sdebug_host(sdp->host); struct sdebug_dev_info *devip; + u8 *cmd = SCpnt->cmnd; + u8 opcode = cmd[0]; int k = 0; ++num_target_resets; @@ -5632,6 +5720,12 @@ static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt) sdev_printk(KERN_INFO, sdp, "%s: %d device(s) found in target\n", __func__, k); + if (sdebug_fail_target_reset(SCpnt)) { + scmd_printk(KERN_INFO, SCpnt, "fail target reset 0x%x\n", + opcode); + return FAILED; + } + return SUCCESS; } @@ -8070,7 +8164,6 @@ static int sdebug_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd) return 0; } - static struct scsi_host_template sdebug_driver_template = { .show_info = scsi_debug_show_info, .write_info = scsi_debug_write_info, @@ -8100,6 +8193,8 @@ static struct scsi_host_template sdebug_driver_template = { .track_queue_depth = 1, .cmd_size = sizeof(struct sdebug_scsi_cmd), .init_cmd_priv = sdebug_init_cmd_priv, + .target_alloc = sdebug_target_alloc, + .target_destroy = sdebug_target_destroy, }; static int sdebug_driver_probe(struct device *dev)