From: Fedor Loshakov <losha...@linux.ibm.com>

There are too many unresolved issues with DIX outside of zfcp
such as wrong protection data on writesame/discard (over device-mapper)
or due to unstable page writes.
This can cause I/O stalls or endless loops or even kernel panics,
or I/O errors due to erroneously failed logical block guard checks.

Therefore, introduce separate zfcp module parameters to individually
select support for:
DIF which should work (zfcp.dif, which used to be DIF+DIX, disabled) or
DIX+DIF which causes trouble (zfcp.dix, new, disabled).

If DIX is enabled, we warn on zfcp driver initialization.

Signed-off-by: Steffen Maier <ma...@linux.ibm.com>
Co-developed-by: Fedor Loshakov <losha...@linux.ibm.com>
Signed-off-by: Fedor Loshakov <losha...@linux.ibm.com>
Reviewed-by: Jens Remus <jre...@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_aux.c  |  3 +++
 drivers/s390/scsi/zfcp_ext.h  |  1 +
 drivers/s390/scsi/zfcp_scsi.c | 10 +++++++---
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 94f4d8fe85e0..08cdc00e8299 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -124,6 +124,9 @@ static int __init zfcp_module_init(void)
 {
        int retval = -ENOMEM;
 
+       if (zfcp_experimental_dix)
+               pr_warn("DIX is enabled. It is experimental and might cause 
problems\n");
+
        zfcp_fsf_qtcb_cache = zfcp_cache_hw_align("zfcp_fsf_qtcb",
                                                  sizeof(struct fsf_qtcb));
        if (!zfcp_fsf_qtcb_cache)
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index bd0c5a9f04cb..0940bef35020 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -144,6 +144,7 @@ extern void zfcp_qdio_close(struct zfcp_qdio *);
 extern void zfcp_qdio_siosl(struct zfcp_adapter *);
 
 /* zfcp_scsi.c */
+extern bool zfcp_experimental_dix;
 extern struct scsi_transport_template *zfcp_scsi_transport_template;
 extern int zfcp_scsi_adapter_register(struct zfcp_adapter *);
 extern void zfcp_scsi_adapter_unregister(struct zfcp_adapter *);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index a8efcb330bc1..2b8c33627460 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -27,7 +27,11 @@ MODULE_PARM_DESC(queue_depth, "Default queue depth for new 
SCSI devices");
 
 static bool enable_dif;
 module_param_named(dif, enable_dif, bool, 0400);
-MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support");
+MODULE_PARM_DESC(dif, "Enable DIF data integrity support (default off)");
+
+bool zfcp_experimental_dix;
+module_param_named(dix, zfcp_experimental_dix, bool, 0400);
+MODULE_PARM_DESC(dix, "Enable experimental DIX (data integrity extension) 
support which implies DIF support (default off)");
 
 static bool allow_lun_scan = true;
 module_param(allow_lun_scan, bool, 0600);
@@ -788,11 +792,11 @@ void zfcp_scsi_set_prot(struct zfcp_adapter *adapter)
        data_div = atomic_read(&adapter->status) &
                   ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED;
 
-       if (enable_dif &&
+       if ((enable_dif || zfcp_experimental_dix) &&
            adapter->adapter_features & FSF_FEATURE_DIF_PROT_TYPE1)
                mask |= SHOST_DIF_TYPE1_PROTECTION;
 
-       if (enable_dif && data_div &&
+       if (zfcp_experimental_dix && data_div &&
            adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) {
                mask |= SHOST_DIX_TYPE1_PROTECTION;
                scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP);
-- 
2.16.4

Reply via email to