scsi: target: tcmu: Make TMR notification optional
authorBodo Stroesser <bstroesser@ts.fujitsu.com>
Sun, 26 Jul 2020 15:35:10 +0000 (17:35 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 29 Jul 2020 02:25:31 +0000 (22:25 -0400)
Add "tmr_notification" configfs attribute to tcmu devices.  If the default
value 0 is used, tcmu only removes aborted commands from qfull_queue.  If
user changes tmr_notification to 1, additionally TMR notifications will be
written to the cmd ring.

Link: https://lore.kernel.org/r/20200726153510.13077-9-bstroesser@ts.fujitsu.com
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Bodo Stroesser <bstroesser@ts.fujitsu.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/target/target_core_user.c

index cb5a561a46e8a9632514c417ce4c636379149421..9b75923505020534a878aa32fc3eafc034ac7776 100644 (file)
@@ -118,6 +118,7 @@ struct tcmu_dev {
 #define TCMU_DEV_BIT_OPEN 0
 #define TCMU_DEV_BIT_BROKEN 1
 #define TCMU_DEV_BIT_BLOCKED 2
+#define TCMU_DEV_BIT_TMR_NOTIFY 3
        unsigned long flags;
 
        struct uio_info uio_info;
@@ -1260,6 +1261,9 @@ tcmu_tmr_notify(struct se_device *se_dev, enum tcm_tmreq_table tmf,
        if (unqueued)
                tcmu_set_next_deadline(&udev->qfull_queue, &udev->qfull_timer);
 
+       if (!test_bit(TCMU_DEV_BIT_TMR_NOTIFY, &udev->flags))
+               goto unlock;
+
        pr_debug("TMR event %d on dev %s, aborted cmds %d, afflicted cmd_ids %d\n",
                 tcmu_tmr_type(tmf), udev->name, i, cmd_cnt);
 
@@ -2706,6 +2710,39 @@ static ssize_t tcmu_emulate_write_cache_store(struct config_item *item,
 }
 CONFIGFS_ATTR(tcmu_, emulate_write_cache);
 
+static ssize_t tcmu_tmr_notification_show(struct config_item *item, char *page)
+{
+       struct se_dev_attrib *da = container_of(to_config_group(item),
+                                       struct se_dev_attrib, da_group);
+       struct tcmu_dev *udev = TCMU_DEV(da->da_dev);
+
+       return snprintf(page, PAGE_SIZE, "%i\n",
+                       test_bit(TCMU_DEV_BIT_TMR_NOTIFY, &udev->flags));
+}
+
+static ssize_t tcmu_tmr_notification_store(struct config_item *item,
+                                          const char *page, size_t count)
+{
+       struct se_dev_attrib *da = container_of(to_config_group(item),
+                                       struct se_dev_attrib, da_group);
+       struct tcmu_dev *udev = TCMU_DEV(da->da_dev);
+       u8 val;
+       int ret;
+
+       ret = kstrtou8(page, 0, &val);
+       if (ret < 0)
+               return ret;
+       if (val > 1)
+               return -EINVAL;
+
+       if (val)
+               set_bit(TCMU_DEV_BIT_TMR_NOTIFY, &udev->flags);
+       else
+               clear_bit(TCMU_DEV_BIT_TMR_NOTIFY, &udev->flags);
+       return count;
+}
+CONFIGFS_ATTR(tcmu_, tmr_notification);
+
 static ssize_t tcmu_block_dev_show(struct config_item *item, char *page)
 {
        struct se_device *se_dev = container_of(to_config_group(item),
@@ -2787,6 +2824,7 @@ static struct configfs_attribute *tcmu_attrib_attrs[] = {
        &tcmu_attr_dev_config,
        &tcmu_attr_dev_size,
        &tcmu_attr_emulate_write_cache,
+       &tcmu_attr_tmr_notification,
        &tcmu_attr_nl_reply_supported,
        NULL,
 };