All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set
@ 2020-05-08 17:23 Benjamin Block
  2020-05-08 17:23 ` [PATCH 1/8] zfcp: move shost modification after QDIO (re-)open into fenced function Benjamin Block
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

Hello Martin, James, linux-scsi folks,

some time ago we noticed - Fedor did - that our DIV and DIX support in
zfcp broke at some point. I tracked that down to a commit made for v5.4
(737eb78e82d5), but we didn't notice it back than, because our CI
doesn't currently run with either DIV, nor DIX enabled (time allowing
this is something we want to improve so we catch stuff like this
earlier). It also turned out that the commit in v5.4 was not really the
root-cause, and was only making the problem visible more easy.

I wrote a rather verbose description/analysis of the problem in patch 8.

In short: zfcp used to allocate/add the shost object for a HBA before
knowing all the HBA's capabilities, and we later patched the shost
object to make more of the capabilities known - including the protection
capabilities. Back when we still had the old blk queue, this worked
fine; after scsi_mod switched to blk-mq and because requests are now
all allocated during allocation time of the blk-mq tag-set, this doesn't
work anymore. Changes we make later to the protection capabilities don't
get reflected into the tag-set's requests, and they are missing parts.
When we then try to send I/O, scsi_mod tries to access the protection
payload data, who are not there, and it crashes the kernel.
    So instead, I now want to allocate/add the shost object for a HBA
after we know all of its base capabilities. This solves the
bug.
    For more details, please see patch 8.

I guess one could say this is a regression, but after thinking about it
for a bit I thought its reasonable to assume that zfcp behaves rather
different here than other drivers, because no one else seems to have
this issue, and so I tried to fix it in zfcp - also with the thought
that this hopefully reduces the risk of further such regressions in the
future.

Because we had this modus operandi for a very long time, I had to touch
many places that assume the shost object was already allocated -
explaining the rather big patchset for a 'fix'. Patches 1 to 7 are
preparations that fix all those places, so we don't access invalid
memory, and we don't loose any information during the HBA
initialization. Patch 8 finally moves the shost object allocation/add.


I assume we can't have this in stable, because the new code depends on a
feature from v5.5 that won't be in all release that would need this
fix... making it rather complicated. Its also too big for stable I
assume.


I tested this extensively internally to hopefully catch any bugs, so far
I have not seen any. I ran our regression-suite with DIV/DIX/NONE; with
I/O, and local/remote cable pulls, switched and p-t-p. Additionally I
had some inject running that would make early initialization fail in
places where we usually already had the shost object allocated; and I
made the shost object allocation/add fail; to see we don't crash, and
can recovery fine once the injects are turned off.


The patches apply fine on both Martin's `5.7/scsi-fixes`, and James'
`fixes` branches. It would be great if you could still get them into 5.7
somehow, but I realise its late in the cycle, and the series might be
too big at this point.


Any comments and reviews are appreciated :)


Benjamin Block (8):
  zfcp: move shost modification after QDIO (re-)open into fenced
    function
  zfcp: move shost updates during xconfig data handling into fenced
    function
  zfcp: move fc_host updates during xport data handling into fenced
    function
  zfcp: fence fc_host updates during link-down handling
  zfcp: move p-t-p port allocation to after xport data
  zfcp: fence adapter status propagation for common statuses
  zfcp: fence early sysfs interfaces for accesses of shost objects
  zfcp: move allocation of the shost object to after xconf- and
    xport-data

 drivers/s390/scsi/zfcp_aux.c   |   5 +-
 drivers/s390/scsi/zfcp_diag.h  |   6 +-
 drivers/s390/scsi/zfcp_erp.c   |  84 ++++++++++++++++++++-
 drivers/s390/scsi/zfcp_ext.h   |  11 +++
 drivers/s390/scsi/zfcp_fsf.c   |  76 +++++--------------
 drivers/s390/scsi/zfcp_qdio.c  |  19 +++--
 drivers/s390/scsi/zfcp_scsi.c  | 131 ++++++++++++++++++++++++++++++---
 drivers/s390/scsi/zfcp_sysfs.c |  16 +++-
 8 files changed, 265 insertions(+), 83 deletions(-)

-- 
2.17.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] zfcp: move shost modification after QDIO (re-)open into fenced function
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
@ 2020-05-08 17:23 ` Benjamin Block
  2020-05-08 17:23 ` [PATCH 2/8] zfcp: move shost updates during xconfig data handling " Benjamin Block
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

When establishing and activating the QDIO queue pair for a FCP device
for the first time, or after an adapter recovery, we publish some of its
characteristics to the scsi host object representing that FCP device.

When moving the scsi host object allocation and registration to after
the first exchange config and exchange port data, this is not possible
for the former case - QDIO open for the first time - because that
happens before exchange config and exchange port data.

Move the scsi host object update into a fenced function that checks
whether the object already exists or not. This way we can repeat that
step later, once we are past the allocation.

Once the first recovery succeeds we don't release the scsi host object
anymore, so further recoveries do work as before.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_ext.h  |  2 ++
 drivers/s390/scsi/zfcp_qdio.c | 19 ++++++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 88294ca0e2ea..d67f31b9b859 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -153,6 +153,8 @@ extern int zfcp_qdio_sbal_get(struct zfcp_qdio *);
 extern int zfcp_qdio_send(struct zfcp_qdio *, struct zfcp_qdio_req *);
 extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *, struct zfcp_qdio_req *,
 				   struct scatterlist *);
+extern void zfcp_qdio_shost_update(struct zfcp_adapter *const adapter,
+				   const struct zfcp_qdio *const qdio);
 extern int zfcp_qdio_open(struct zfcp_qdio *);
 extern void zfcp_qdio_close(struct zfcp_qdio *);
 extern void zfcp_qdio_siosl(struct zfcp_adapter *);
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 26702b56a7ab..3a7f3374d10a 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -4,7 +4,7 @@
  *
  * Setup and helper functions to access QDIO.
  *
- * Copyright IBM Corp. 2002, 2017
+ * Copyright IBM Corp. 2002, 2020
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -342,6 +342,18 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio)
 	atomic_set(&qdio->req_q_free, 0);
 }
 
+void zfcp_qdio_shost_update(struct zfcp_adapter *const adapter,
+			    const struct zfcp_qdio *const qdio)
+{
+	struct Scsi_Host *const shost = adapter->scsi_host;
+
+	if (shost == NULL)
+		return;
+
+	shost->sg_tablesize = qdio->max_sbale_per_req;
+	shost->max_sectors = qdio->max_sbale_per_req * 8;
+}
+
 /**
  * zfcp_qdio_open - prepare and initialize response queue
  * @qdio: pointer to struct zfcp_qdio
@@ -420,10 +432,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
 	atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q);
 	atomic_or(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
 
-	if (adapter->scsi_host) {
-		adapter->scsi_host->sg_tablesize = qdio->max_sbale_per_req;
-		adapter->scsi_host->max_sectors = qdio->max_sbale_per_req * 8;
-	}
+	zfcp_qdio_shost_update(adapter, qdio);
 
 	return 0;
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/8] zfcp: move shost updates during xconfig data handling into fenced function
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
  2020-05-08 17:23 ` [PATCH 1/8] zfcp: move shost modification after QDIO (re-)open into fenced function Benjamin Block
@ 2020-05-08 17:23 ` Benjamin Block
  2020-05-08 17:23 ` [PATCH 3/8] zfcp: move fc_host updates during xport " Benjamin Block
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

When executing exchange config data for a FCP device for the first time,
or after an adapter recovery, we update several properties of the scsi
host or fibre channel host object that represent that FCP device.

When moving the scsi host object allocation and registration - and thus
also the fibre channel host object allocation - to after the first
exchange config and exchange port data, this is not possible for the
former case.

Move all these update into separate, and fenced function that first
checks whether the scsi host object already exists or not, before making
the updates.

During the first ever exchange config data in the adapter life cycle
this will make the exchange config data handler skip over this update
step, but we can repeat it later, after we allocated the scsi host
object.

For any further recovery of that adapter the work flow is only changed
slightly because then the scsi host object already exists and we don't
free it until we release the adapter completely at the end of its life
cycle.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_ext.h  |  5 +++
 drivers/s390/scsi/zfcp_fsf.c  | 48 +++--------------------
 drivers/s390/scsi/zfcp_scsi.c | 72 ++++++++++++++++++++++++++++++++++-
 3 files changed, 82 insertions(+), 43 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index d67f31b9b859..4c4be754cf6e 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -125,6 +125,7 @@ extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *,
 extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *);
 extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *,
 					    struct fsf_qtcb_bottom_port *);
+extern u32 zfcp_fsf_convert_portspeed(u32 fsf_speed);
 extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
 extern int zfcp_fsf_status_read(struct zfcp_qdio *);
 extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
@@ -171,6 +172,10 @@ extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *);
 extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *);
 extern void zfcp_scsi_set_prot(struct zfcp_adapter *);
 extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int);
+extern void zfcp_scsi_shost_update_config_data(
+	struct zfcp_adapter *const adapter,
+	const struct fsf_qtcb_bottom_config *const bottom,
+	const bool bottom_incomplete);
 
 /* zfcp_sysfs.c */
 extern const struct attribute_group *zfcp_unit_attr_groups[];
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 111fe3fc32d7..54edfcbe84ce 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -479,7 +479,7 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
 #define ZFCP_FSF_PORTSPEED_128GBIT	(1 <<  8)
 #define ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED (1 << 15)
 
-static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed)
+u32 zfcp_fsf_convert_portspeed(u32 fsf_speed)
 {
 	u32 fdmi_speed = 0;
 	if (fsf_speed & ZFCP_FSF_PORTSPEED_1GBIT)
@@ -509,64 +509,36 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
 {
 	struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config;
 	struct zfcp_adapter *adapter = req->adapter;
-	struct Scsi_Host *shost = adapter->scsi_host;
-	struct fc_els_flogi *nsp, *plogi;
+	struct fc_els_flogi *plogi;
 
 	/* adjust pointers for missing command code */
-	nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param
-					- sizeof(u32));
 	plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload
 					- sizeof(u32));
 
 	if (req->data)
 		memcpy(req->data, bottom, sizeof(*bottom));
 
-	snprintf(fc_host_manufacturer(shost), FC_SERIAL_NUMBER_SIZE, "%s",
-		 "IBM");
-	fc_host_port_name(shost) = be64_to_cpu(nsp->fl_wwpn);
-	fc_host_node_name(shost) = be64_to_cpu(nsp->fl_wwnn);
-	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
-
 	adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK;
 	adapter->stat_read_buf_num = max(bottom->status_read_buf_num,
 					 (u16)FSF_STATUS_READS_RECOM);
 
-	zfcp_scsi_set_prot(adapter);
-
 	/* no error return above here, otherwise must fix call chains */
 	/* do not evaluate invalid fields */
 	if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE)
 		return 0;
 
-	fc_host_port_id(shost) = ntoh24(bottom->s_id);
-	fc_host_speed(shost) =
-		zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
-
 	adapter->hydra_version = bottom->adapter_type;
-	snprintf(fc_host_model(shost), FC_SYMBOLIC_NAME_SIZE, "0x%04x",
-		 bottom->adapter_type);
 
 	switch (bottom->fc_topology) {
 	case FSF_TOPO_P2P:
 		adapter->peer_d_id = ntoh24(bottom->peer_d_id);
 		adapter->peer_wwpn = be64_to_cpu(plogi->fl_wwpn);
 		adapter->peer_wwnn = be64_to_cpu(plogi->fl_wwnn);
-		fc_host_port_type(shost) = FC_PORTTYPE_PTP;
-		fc_host_fabric_name(shost) = 0;
 		break;
 	case FSF_TOPO_FABRIC:
-		fc_host_fabric_name(shost) = be64_to_cpu(plogi->fl_wwnn);
-		if (bottom->connection_features & FSF_FEATURE_NPIV_MODE)
-			fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
-		else
-			fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
 		break;
 	case FSF_TOPO_AL:
-		fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
-		fc_host_fabric_name(shost) = 0;
-		fallthrough;
 	default:
-		fc_host_fabric_name(shost) = 0;
 		dev_err(&adapter->ccw_device->dev,
 			"Unknown or unsupported arbitrated loop "
 			"fibre channel topology detected\n");
@@ -584,13 +556,10 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
 		&adapter->diagnostics->config_data.header;
 	struct fsf_qtcb *qtcb = req->qtcb;
 	struct fsf_qtcb_bottom_config *bottom = &qtcb->bottom.config;
-	struct Scsi_Host *shost = adapter->scsi_host;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		return;
 
-	snprintf(fc_host_firmware_version(shost), FC_VERSION_STRING_SIZE,
-		 "0x%08x", bottom->lic_version);
 	adapter->fsf_lic_version = bottom->lic_version;
 	adapter->adapter_features = bottom->adapter_features;
 	adapter->connection_features = bottom->connection_features;
@@ -606,6 +575,7 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
 		 */
 		zfcp_diag_update_xdata(diag_hdr, bottom, false);
 
+		zfcp_scsi_shost_update_config_data(adapter, bottom, false);
 		if (zfcp_fsf_exchange_config_evaluate(req))
 			return;
 
@@ -630,6 +600,8 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
 				&adapter->status);
 		zfcp_fsf_link_down_info_eval(req,
 			&qtcb->header.fsf_status_qual.link_down_info);
+
+		zfcp_scsi_shost_update_config_data(adapter, bottom, true);
 		if (zfcp_fsf_exchange_config_evaluate(req))
 			return;
 		break;
@@ -638,16 +610,8 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
 		return;
 	}
 
-	if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
+	if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)
 		adapter->hardware_version = bottom->hardware_version;
-		snprintf(fc_host_hardware_version(shost),
-			 FC_VERSION_STRING_SIZE,
-			 "0x%08x", bottom->hardware_version);
-		memcpy(fc_host_serial_number(shost), bottom->serial_number,
-		       min(FC_SERIAL_NUMBER_SIZE, 17));
-		EBCASC(fc_host_serial_number(shost),
-		       min(FC_SERIAL_NUMBER_SIZE, 17));
-	}
 
 	if (FSF_QTCB_CURRENT_VERSION < bottom->low_qtcb_version) {
 		dev_err(&adapter->ccw_device->dev,
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 13d873f806e4..e1281a1ce488 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -4,7 +4,7 @@
  *
  * Interface to Linux SCSI midlayer.
  *
- * Copyright IBM Corp. 2002, 2018
+ * Copyright IBM Corp. 2002, 2020
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -841,6 +841,76 @@ void zfcp_scsi_dif_sense_error(struct scsi_cmnd *scmd, int ascq)
 	set_host_byte(scmd, DID_SOFT_ERROR);
 }
 
+void zfcp_scsi_shost_update_config_data(
+	struct zfcp_adapter *const adapter,
+	const struct fsf_qtcb_bottom_config *const bottom,
+	const bool bottom_incomplete)
+{
+	struct Scsi_Host *const shost = adapter->scsi_host;
+	const struct fc_els_flogi *nsp, *plogi;
+
+	if (shost == NULL)
+		return;
+
+	snprintf(fc_host_firmware_version(shost), FC_VERSION_STRING_SIZE,
+		 "0x%08x", bottom->lic_version);
+
+	if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
+		snprintf(fc_host_hardware_version(shost),
+			 FC_VERSION_STRING_SIZE,
+			 "0x%08x", bottom->hardware_version);
+		memcpy(fc_host_serial_number(shost), bottom->serial_number,
+		       min(FC_SERIAL_NUMBER_SIZE, 17));
+		EBCASC(fc_host_serial_number(shost),
+		       min(FC_SERIAL_NUMBER_SIZE, 17));
+	}
+
+	/* adjust pointers for missing command code */
+	nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param
+					- sizeof(u32));
+	plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload
+					- sizeof(u32));
+
+	snprintf(fc_host_manufacturer(shost), FC_SERIAL_NUMBER_SIZE, "%s",
+		 "IBM");
+	fc_host_port_name(shost) = be64_to_cpu(nsp->fl_wwpn);
+	fc_host_node_name(shost) = be64_to_cpu(nsp->fl_wwnn);
+	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
+
+	zfcp_scsi_set_prot(adapter);
+
+	/* do not evaluate invalid fields */
+	if (bottom_incomplete)
+		return;
+
+	fc_host_port_id(shost) = ntoh24(bottom->s_id);
+	fc_host_speed(shost) =
+		zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
+
+	snprintf(fc_host_model(shost), FC_SYMBOLIC_NAME_SIZE, "0x%04x",
+		 bottom->adapter_type);
+
+	switch (bottom->fc_topology) {
+	case FSF_TOPO_P2P:
+		fc_host_port_type(shost) = FC_PORTTYPE_PTP;
+		fc_host_fabric_name(shost) = 0;
+		break;
+	case FSF_TOPO_FABRIC:
+		fc_host_fabric_name(shost) = be64_to_cpu(plogi->fl_wwnn);
+		if (bottom->connection_features & FSF_FEATURE_NPIV_MODE)
+			fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
+		else
+			fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
+		break;
+	case FSF_TOPO_AL:
+		fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
+		fallthrough;
+	default:
+		fc_host_fabric_name(shost) = 0;
+		break;
+	}
+}
+
 struct fc_function_template zfcp_transport_functions = {
 	.show_starget_port_id = 1,
 	.show_starget_port_name = 1,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/8] zfcp: move fc_host updates during xport data handling into fenced function
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
  2020-05-08 17:23 ` [PATCH 1/8] zfcp: move shost modification after QDIO (re-)open into fenced function Benjamin Block
  2020-05-08 17:23 ` [PATCH 2/8] zfcp: move shost updates during xconfig data handling " Benjamin Block
@ 2020-05-08 17:23 ` Benjamin Block
  2020-05-08 17:23 ` [PATCH 4/8] zfcp: fence fc_host updates during link-down handling Benjamin Block
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

When executing exchange port data for a FCP device for the first time, or
after an adapter recovery, we update several properties of the fibre
channel host object which represents that FCP device.

When moving the scsi host object allocation and registration - and thus
also the fibre channel host object allocation - to after the first
exchange config and exchange port data, this is not possible for the
former case.

Move all these update into separate, and fenced function that first
checks whether the scsi host object already exists or not, before making
the updates.

During the first ever exchange port data in the adapter life cycle
this will make the exchange port data handler skip over this update
step, but we can repeat it later, after we allocated the scsi host
object.

For any further recovery of that adapter the work flow is only changed
slightly because then the scsi host object already exists and we don't
free it until we release the adapter completely at the end of its life
cycle.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_ext.h  |  3 +++
 drivers/s390/scsi/zfcp_fsf.c  | 12 +++---------
 drivers/s390/scsi/zfcp_scsi.c | 19 +++++++++++++++++++
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 4c4be754cf6e..5dc9bdc5803f 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -176,6 +176,9 @@ extern void zfcp_scsi_shost_update_config_data(
 	struct zfcp_adapter *const adapter,
 	const struct fsf_qtcb_bottom_config *const bottom,
 	const bool bottom_incomplete);
+extern void zfcp_scsi_shost_update_port_data(
+	struct zfcp_adapter *const adapter,
+	const struct fsf_qtcb_bottom_port *const bottom);
 
 /* zfcp_sysfs.c */
 extern const struct attribute_group *zfcp_unit_attr_groups[];
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 54edfcbe84ce..bfb567a1d7bf 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -725,19 +725,10 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)
 {
 	struct zfcp_adapter *adapter = req->adapter;
 	struct fsf_qtcb_bottom_port *bottom = &req->qtcb->bottom.port;
-	struct Scsi_Host *shost = adapter->scsi_host;
 
 	if (req->data)
 		memcpy(req->data, bottom, sizeof(*bottom));
 
-	fc_host_permanent_port_name(shost) = bottom->wwpn;
-	fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
-	fc_host_supported_speeds(shost) =
-		zfcp_fsf_convert_portspeed(bottom->supported_speed);
-	memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types,
-	       FC_FC4_LIST_SIZE);
-	memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types,
-	       FC_FC4_LIST_SIZE);
 	if (adapter->adapter_features & FSF_FEATURE_FC_SECURITY)
 		adapter->fc_security_algorithms =
 			bottom->fc_security_algorithms;
@@ -764,6 +755,7 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
 		 */
 		zfcp_diag_update_xdata(diag_hdr, bottom, false);
 
+		zfcp_scsi_shost_update_port_data(req->adapter, bottom);
 		zfcp_fsf_exchange_port_evaluate(req);
 		break;
 	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
@@ -772,6 +764,8 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
 
 		zfcp_fsf_link_down_info_eval(req,
 			&qtcb->header.fsf_status_qual.link_down_info);
+
+		zfcp_scsi_shost_update_port_data(req->adapter, bottom);
 		zfcp_fsf_exchange_port_evaluate(req);
 		break;
 	}
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index e1281a1ce488..f98e4015a0ed 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -911,6 +911,25 @@ void zfcp_scsi_shost_update_config_data(
 	}
 }
 
+void zfcp_scsi_shost_update_port_data(
+	struct zfcp_adapter *const adapter,
+	const struct fsf_qtcb_bottom_port *const bottom)
+{
+	struct Scsi_Host *const shost = adapter->scsi_host;
+
+	if (shost == NULL)
+		return;
+
+	fc_host_permanent_port_name(shost) = bottom->wwpn;
+	fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
+	fc_host_supported_speeds(shost) =
+		zfcp_fsf_convert_portspeed(bottom->supported_speed);
+	memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types,
+	       FC_FC4_LIST_SIZE);
+	memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types,
+	       FC_FC4_LIST_SIZE);
+}
+
 struct fc_function_template zfcp_transport_functions = {
 	.show_starget_port_id = 1,
 	.show_starget_port_name = 1,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/8] zfcp: fence fc_host updates during link-down handling
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
                   ` (2 preceding siblings ...)
  2020-05-08 17:23 ` [PATCH 3/8] zfcp: move fc_host updates during xport " Benjamin Block
@ 2020-05-08 17:23 ` Benjamin Block
  2020-05-08 17:23 ` [PATCH 5/8] zfcp: move p-t-p port allocation to after xport data Benjamin Block
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

When receiving a notification that a FCP device lost its local link we
usually update the fibre channel host object which represents that FCP
device to reflect that.

This notification/information can also surface when the FCP device is
running through adapter recovery (exchange config and exchange port data
return incomplete).

When moving the scsi host object allocation and registration  - and thus
also the fibre channel host object allocation - to after the first
exchange config and exchange port data, and this happens during the very
first adapter recovery, these updates can not be done until after the
scsi host object is allocated.

Reorder the fc_host updates in zfcp_fsf_fc_host_link_down() so that they
only happen after a check of whether the scsi host object is already
allocated or not.

During the first adapter recovery this will cause the skip of these
updates if a link-down condition is detected, but we can repeat them
after we allocated the scsi host object, if necessary.

For any further link-down handling the only changes in the work flow are
the slightly reordered assignments in zfcp_fsf_fc_host_link_down().

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_fsf.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index bfb567a1d7bf..8c4b690e329e 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -124,17 +124,21 @@ static void zfcp_fsf_fc_host_link_down(struct zfcp_adapter *adapter)
 {
 	struct Scsi_Host *shost = adapter->scsi_host;
 
+	adapter->hydra_version = 0;
+	adapter->peer_wwpn = 0;
+	adapter->peer_wwnn = 0;
+	adapter->peer_d_id = 0;
+
+	/* if there is no shost yet, we have nothing to zero-out */
+	if (shost == NULL)
+		return;
+
 	fc_host_port_id(shost) = 0;
 	fc_host_fabric_name(shost) = 0;
 	fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
 	fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
-	adapter->hydra_version = 0;
 	snprintf(fc_host_model(shost), FC_SYMBOLIC_NAME_SIZE, "0x%04x", 0);
 	memset(fc_host_active_fc4s(shost), 0, FC_FC4_LIST_SIZE);
-
-	adapter->peer_wwpn = 0;
-	adapter->peer_wwnn = 0;
-	adapter->peer_d_id = 0;
 }
 
 static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/8] zfcp: move p-t-p port allocation to after xport data
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
                   ` (3 preceding siblings ...)
  2020-05-08 17:23 ` [PATCH 4/8] zfcp: fence fc_host updates during link-down handling Benjamin Block
@ 2020-05-08 17:23 ` Benjamin Block
  2020-05-08 17:23 ` [PATCH 6/8] zfcp: fence adapter status propagation for common statuses Benjamin Block
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

When doing the very first adapter recovery - initialization - for a FCP
device in a point-to-point topology we also allocate the port object
corresponding to the attached remote port, and trigger a port recovery
for it that will run after the adapter recovery finished.

Right now this happens right after we finished with the exchange config
data command, and uses the fibre channel host object corresponding to
the FCP device to determine whether a point-to-point topology is used.

When moving the scsi host object allocation and registration - and thus
also the fibre channel host object allocation - to after the first
exchange config and exchange port data, this use of the fc_host object
is not possible anymore at that point in the work flow.

But the allocation and recovery trigger doesn't have notable
side-effects on the following exchange port data processing, so we can
move those to after xport data, and thus also to after the scsi host
object allocation, once we move it. Then the fc_host object can be used
again, like it is now.

For any further adapter recoveries this doesn't change anything, because
at that point the port object already exists and recovery is triggered
elsewhere for existing port objects.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_erp.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 3d0bc000f500..356f51d2bbee 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -4,7 +4,7 @@
  *
  * Error Recovery Procedures (ERP).
  *
- * Copyright IBM Corp. 2002, 2017
+ * Copyright IBM Corp. 2002, 2020
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -768,10 +768,14 @@ static enum zfcp_erp_act_result zfcp_erp_adapter_strat_fsf_xconf(
 	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_XCONFIG_OK))
 		return ZFCP_ERP_FAILED;
 
+	return ZFCP_ERP_SUCCEEDED;
+}
+
+static void
+zfcp_erp_adapter_strategy_open_ptp_port(struct zfcp_adapter *const adapter)
+{
 	if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
 		zfcp_erp_enqueue_ptp_port(adapter);
-
-	return ZFCP_ERP_SUCCEEDED;
 }
 
 static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf_xport(
@@ -809,6 +813,8 @@ static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf(
 	if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED)
 		return ZFCP_ERP_FAILED;
 
+	zfcp_erp_adapter_strategy_open_ptp_port(act->adapter);
+
 	if (mempool_resize(act->adapter->pool.sr_data,
 			   act->adapter->stat_read_buf_num))
 		return ZFCP_ERP_FAILED;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/8] zfcp: fence adapter status propagation for common statuses
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
                   ` (4 preceding siblings ...)
  2020-05-08 17:23 ` [PATCH 5/8] zfcp: move p-t-p port allocation to after xport data Benjamin Block
@ 2020-05-08 17:23 ` Benjamin Block
  2020-05-08 17:23 ` [PATCH 7/8] zfcp: fence early sysfs interfaces for accesses of shost objects Benjamin Block
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

Common status flags that all main objects - adapter, port, and unit -
support are propagated to sub-objects when set or cleared. For instance,
when setting the status ZFCP_STATUS_COMMON_ERP_INUSE for an adapter
object, we will propagate this to all its child ports and units - same
for when clearing a common status flag.

Units of an adapter object are enumerated via __shost_for_each_device()
over the scsi host object of the corresponding adapter.

Once we move the scsi host object allocation and registration to after
the first exchange config and exchange port data, this won't be possible
for cases where we set or clear common statuses during the very first
adapter recovery.

But since we won't have any port or unit objects yet at that point of
time, we can just fence the status propagation for cases where the scsi
host object is not yet set in the adapter object. It won't change any
effective status propagations, but will prevent us from dereferencing
invalid pointers.

For any later point in the work flow the scsi host object will be set
and thus nothing is changed then.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_erp.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 356f51d2bbee..283bcb985655 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1642,6 +1642,13 @@ void zfcp_erp_set_adapter_status(struct zfcp_adapter *adapter, u32 mask)
 		atomic_or(common_mask, &port->status);
 	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 
+	/*
+	 * if `scsi_host` is missing, xconfig/xport data has never completed
+	 * yet, so we can't access it, but there are also no SDEVs yet
+	 */
+	if (adapter->scsi_host == NULL)
+		return;
+
 	spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
 	__shost_for_each_device(sdev, adapter->scsi_host)
 		atomic_or(common_mask, &sdev_to_zfcp(sdev)->status);
@@ -1679,6 +1686,13 @@ void zfcp_erp_clear_adapter_status(struct zfcp_adapter *adapter, u32 mask)
 	}
 	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 
+	/*
+	 * if `scsi_host` is missing, xconfig/xport data has never completed
+	 * yet, so we can't access it, but there are also no SDEVs yet
+	 */
+	if (adapter->scsi_host == NULL)
+		return;
+
 	spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
 	__shost_for_each_device(sdev, adapter->scsi_host) {
 		atomic_andnot(common_mask, &sdev_to_zfcp(sdev)->status);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/8] zfcp: fence early sysfs interfaces for accesses of shost objects
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
                   ` (5 preceding siblings ...)
  2020-05-08 17:23 ` [PATCH 6/8] zfcp: fence adapter status propagation for common statuses Benjamin Block
@ 2020-05-08 17:23 ` Benjamin Block
  2020-05-08 17:23 ` [PATCH 8/8] zfcp: move allocation of the shost object to after xconf- and xport-data Benjamin Block
  2020-05-12  3:28 ` [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Martin K. Petersen
  8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

When setting an adapter online for the first time, we also create a
couple of entries for it in the sysfs device tree. This is also true
even if the adapter has not yet ever gone successfully through exchange
config and exchange port data.

When moving the scsi host object allocation and registration to after
the first exchange config and exchange port data, this make
the `port_rescan` attribute susceptible to invalid pointer-dereferences
of the shost field before the adapter is fully initialized.

When written to, it schedules a `scan_work` item that will in turn make
use of the associated fibre channel host object to check the topology
used for this FCP device.

Because scanning for remote ports can't be done successfully without
completing exchange config and exchange port data first, we can simply
fence `port_rescan`, and so prevent the illegal access.

As with cases where we can't get a reference to the adapter, we also
return -ENODEV here. Applications need to handle that errno today
already.

After a successful allocation of the scsi host object nothing changes in
the work flow.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_sysfs.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 7ec30ded0169..8d9662e8b717 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -216,10 +216,22 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+	int retval = 0;
 
 	if (!adapter)
 		return -ENODEV;
 
+	/*
+	 * If `scsi_host` is missing, we can't schedule `scan_work`, as it
+	 * makes use of the corresponding fc_host object. But this state is
+	 * only possible if xconfig/xport data has never completed yet,
+	 * and we couldn't successfully scan for ports anyway.
+	 */
+	if (adapter->scsi_host == NULL) {
+		retval = -ENODEV;
+		goto out;
+	}
+
 	/*
 	 * Users wish is our command: immediately schedule and flush a
 	 * worker to conduct a synchronous port scan, that is, neither
@@ -227,9 +239,9 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
 	 */
 	queue_delayed_work(adapter->work_queue, &adapter->scan_work, 0);
 	flush_delayed_work(&adapter->scan_work);
+out:
 	zfcp_ccw_adapter_put(adapter);
-
-	return (ssize_t) count;
+	return retval ? retval : (ssize_t) count;
 }
 static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
 		     zfcp_sysfs_port_rescan_store);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 8/8] zfcp: move allocation of the shost object to after xconf- and xport-data
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
                   ` (6 preceding siblings ...)
  2020-05-08 17:23 ` [PATCH 7/8] zfcp: fence early sysfs interfaces for accesses of shost objects Benjamin Block
@ 2020-05-08 17:23 ` Benjamin Block
  2020-05-12  3:28 ` [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Martin K. Petersen
  8 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-08 17:23 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen
  Cc: Benjamin Block, Steffen Maier, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Fedor Loshakov, Julian Wiedmann,
	linux-scsi, linux-s390

At the moment we allocate and register the Scsi_Host object
corresponding to a zfcp adapter (FCP device) very early in the life
cycle of the adapter - even before we fully discover and initialize the
underlying firmware/hardware. This had the advantage that we could
already use the Scsi_Host object, and fill in all its information during
said discover and initialize.

Due to
commit 737eb78e82d5 ("block: Delay default elevator initialization")
(first released in v5.4), we noticed a regression that would prevent us
from using any storage volume if zfcp is configured with support for DIF
or DIX (zfcp.dif=1 || zfcp.dix=1). Doing so would result in an illegal
memory access as soon as the first request is sent with such an
configuration. As example for a crash resulting from this:

  scsi host0: scsi_eh_0: sleeping
  scsi host0: zfcp
  qdio: 0.0.1900 ZFCP on SC 4bd using AI:1 QEBSM:0 PRI:1 TDD:1 SIGA: W AP
  scsi 0:0:0:0: scsi scan: INQUIRY pass 1 length 36
  Unable to handle kernel pointer dereference in virtual kernel address space
  Failing address: 0000000000000000 TEID: 0000000000000483
  Fault in home space mode while using kernel ASCE.
  AS:0000000035c7c007 R3:00000001effcc007 S:00000001effd1000 P:000000000000003d
  Oops: 0004 ilc:3 [#1] PREEMPT SMP DEBUG_PAGEALLOC
  Modules linked in: ...
  CPU: 1 PID: 783 Comm: kworker/u760:5 Kdump: loaded Not tainted 5.6.0-rc2-bb-next+ #1
  Hardware name: ...
  Workqueue: scsi_wq_0 fc_scsi_scan_rport [scsi_transport_fc]
  Krnl PSW : 0704e00180000000 000003ff801fcdae (scsi_queue_rq+0x436/0x740 [scsi_mod])
             R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3
  Krnl GPRS: 0fffffffffffffff 0000000000000000 0000000187150120 0000000000000000
             000003ff80223d20 000000000000018e 000000018adc6400 0000000187711000
             000003e0062337e8 00000001ae719000 0000000187711000 0000000187150000
             00000001ab808100 0000000187150120 000003ff801fcd74 000003e0062336a0
  Krnl Code: 000003ff801fcd9e: e310a35c0012        lt      %r1,860(%r10)
             000003ff801fcda4: a7840010           brc     8,000003ff801fcdc4
            #000003ff801fcda8: e310b2900004       lg      %r1,656(%r11)
            >000003ff801fcdae: d71710001000       xc      0(24,%r1),0(%r1)
             000003ff801fcdb4: e310b2900004       lg      %r1,656(%r11)
             000003ff801fcdba: 41201018           la      %r2,24(%r1)
             000003ff801fcdbe: e32010000024       stg     %r2,0(%r1)
             000003ff801fcdc4: b904002b           lgr     %r2,%r11
  Call Trace:
   [<000003ff801fcdae>] scsi_queue_rq+0x436/0x740 [scsi_mod]
  ([<000003ff801fcd74>] scsi_queue_rq+0x3fc/0x740 [scsi_mod])
   [<00000000349c9970>] blk_mq_dispatch_rq_list+0x390/0x680
   [<00000000349d1596>] blk_mq_sched_dispatch_requests+0x196/0x1a8
   [<00000000349c7a04>] __blk_mq_run_hw_queue+0x144/0x160
   [<00000000349c7ab6>] __blk_mq_delay_run_hw_queue+0x96/0x228
   [<00000000349c7d5a>] blk_mq_run_hw_queue+0xd2/0xe0
   [<00000000349d194a>] blk_mq_sched_insert_request+0x192/0x1d8
   [<00000000349c17b8>] blk_execute_rq_nowait+0x80/0x90
   [<00000000349c1856>] blk_execute_rq+0x6e/0xb0
   [<000003ff801f8ac2>] __scsi_execute+0xe2/0x1f0 [scsi_mod]
   [<000003ff801fef98>] scsi_probe_and_add_lun+0x358/0x840 [scsi_mod]
   [<000003ff8020001c>] __scsi_scan_target+0xc4/0x228 [scsi_mod]
   [<000003ff80200254>] scsi_scan_target+0xd4/0x100 [scsi_mod]
   [<000003ff802d8b96>] fc_scsi_scan_rport+0x96/0xc0 [scsi_transport_fc]
   [<0000000034245ce8>] process_one_work+0x458/0x7d0
   [<00000000342462a2>] worker_thread+0x242/0x448
   [<0000000034250994>] kthread+0x15c/0x170
   [<0000000034e1979c>] ret_from_fork+0x30/0x38
  INFO: lockdep is turned off.
  Last Breaking-Event-Address:
   [<000003ff801fbc36>] scsi_add_cmd_to_list+0x9e/0xa8 [scsi_mod]
  Kernel panic - not syncing: Fatal exception: panic_on_oops

While this issue is exposed by the commit named above, this is only by
accident. The real issue exists for longer already - basically since it's
possible to use blk-mq via scsi-mq, and blk-mq pre-allocates all
requests for a tag-set during initialization of the same. For a given
Scsi_Host object this is done when adding the object to the midlayer
(`scsi_add_host()` and such). In `scsi_mq_setup_tags()` the midlayer
calculates how much memory is required for a single scsi_cmnd, and its
additional data, which also might include space for additional
protection data - depending on whether the Scsi_Host has any form of
protection capabilities (`scsi_host_get_prot()`).

The problem is now thus, because zfcp does this step before we actually
know whether the firmware/hardware has these capabilities, we don't set
any protection capabilities in the Scsi_Host object. And so, no space is
allocated for additional protection data for requests in the Scsi_Host
tag-set.

Once we go through discover and initialize the FCP device
firmware/hardware fully (this is done via the firmware commands
"Exchange Config Data" and "Exchange Port Data") we find out whether it
actually supports DIF and DIX, and we set the corresponding capabilities
in the Scsi_Host object (in `zfcp_scsi_set_prot()`). Now the Scsi_Host
potentially has protection capabilities, but the already allocated
requests in the tag-set don't have any space allocated for that.

When we then trigger target scanning or add scsi_devices manually, the
midlayer will use requests from that tag-set, and before sending most
requests, it will also call `scsi_mq_prep_fn()`. To prepare the
scsi_cmnd this function will check again whether the used Scsi_Host has
any protection capabilities - and now it potentially has - and if so, it
will try to initialize the assumed to be preallocated structures and
thus it causes the crash, like shown above.

Before delaying the default elevator initialization with the commit
named above, we always would also allocate an elevator for any
scsi_device before ever sending any requests - in contrast to now, where
we do it after device-probing. That elevator in turn would have its own
tag-set, and that is initialized after we went through discovery and
initialization of the underlying firmware/hardware. So requests from
that tag-set can be allocated properly, and if used - unless the user
changes/disabled the default elevator - this would hide the underlying
issue.

To fix this for any configuration - with or without an elevator - we
move the allocation and registration of the Scsi_Host object for a given
FCP device to after the first complete discovery and initialization of
the underlying firmware/hardware. By doing that we can make all basic
properties of the Scsi_Host known to the midlayer by the time we call
`scsi_add_host()`, including whether we have any protection
capabilities.

To do that we have to delay all the accesses that we would have done in
the past during discovery and initialization, and do them instead once
we are finished with it. The previous patches ramp up to this by fencing
and factoring out all these accesses, and make it possible to re-do them
later on. In addition we make also use of the diagnostic buffers we
recently added with
commit 92953c6e0aa7 ("scsi: zfcp: signal incomplete or error for sync exchange config/port data")
commit 7e418833e689 ("scsi: zfcp: diagnostics buffer caching and use for exchange port data")
commit 088210233e6f ("scsi: zfcp: add diagnostics buffer for exchange config data")
(first released in v5.5), because these already cache all the
information we need for that "re-do operation" - the information cached
are always updated during xconf or xport data, so it won't be stale.

In addition to the move and re-do, this patch also updates the
function-documentation of `zfcp_scsi_adapter_register()` and changes how
it reports if a Scsi_Host object already exists. In that case future
recovery-operations can skip this step completely and behave much like
they would do in the past - zfcp does not release a once allocated
Scsi_Host object unless the corresponding FCP device is deconstructed
completely.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
---
 drivers/s390/scsi/zfcp_aux.c  |  5 ++-
 drivers/s390/scsi/zfcp_diag.h |  6 ++--
 drivers/s390/scsi/zfcp_erp.c  | 58 +++++++++++++++++++++++++++++++++++
 drivers/s390/scsi/zfcp_ext.h  |  1 +
 drivers/s390/scsi/zfcp_fsf.c  |  2 +-
 drivers/s390/scsi/zfcp_scsi.c | 40 ++++++++++++++++++------
 6 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 09ec846fe01d..18b713a616de 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -4,7 +4,7 @@
  *
  * Module interface and handling of zfcp data structures.
  *
- * Copyright IBM Corp. 2002, 2018
+ * Copyright IBM Corp. 2002, 2020
  */
 
 /*
@@ -415,8 +415,7 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
 
 	adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM;
 
-	if (!zfcp_scsi_adapter_register(adapter))
-		return adapter;
+	return adapter;
 
 failed:
 	zfcp_adapter_unregister(adapter);
diff --git a/drivers/s390/scsi/zfcp_diag.h b/drivers/s390/scsi/zfcp_diag.h
index b9c93d15f67c..3852367f15f6 100644
--- a/drivers/s390/scsi/zfcp_diag.h
+++ b/drivers/s390/scsi/zfcp_diag.h
@@ -4,7 +4,7 @@
  *
  * Definitions for handling diagnostics in the the zfcp device driver.
  *
- * Copyright IBM Corp. 2018
+ * Copyright IBM Corp. 2018, 2020
  */
 
 #ifndef ZFCP_DIAG_H
@@ -56,11 +56,11 @@ struct zfcp_diag_adapter {
 
 	unsigned long	max_age;
 
-	struct {
+	struct zfcp_diag_adapter_port_data {
 		struct zfcp_diag_header		header;
 		struct fsf_qtcb_bottom_port	data;
 	} port_data;
-	struct {
+	struct zfcp_diag_adapter_config_data {
 		struct zfcp_diag_header		header;
 		struct fsf_qtcb_bottom_config	data;
 	} config_data;
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 283bcb985655..db320dab1fee 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -14,6 +14,7 @@
 #include <linux/bug.h>
 #include "zfcp_ext.h"
 #include "zfcp_reqlist.h"
+#include "zfcp_diag.h"
 
 #define ZFCP_MAX_ERPS                   3
 
@@ -804,6 +805,59 @@ static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf_xport(
 	return ZFCP_ERP_SUCCEEDED;
 }
 
+static enum zfcp_erp_act_result
+zfcp_erp_adapter_strategy_alloc_shost(struct zfcp_adapter *const adapter)
+{
+	struct zfcp_diag_adapter_config_data *const config_data =
+		&adapter->diagnostics->config_data;
+	struct zfcp_diag_adapter_port_data *const port_data =
+		&adapter->diagnostics->port_data;
+	unsigned long flags;
+	int rc;
+
+	rc = zfcp_scsi_adapter_register(adapter);
+	if (rc == -EEXIST)
+		return ZFCP_ERP_SUCCEEDED;
+	else if (rc)
+		return ZFCP_ERP_FAILED;
+
+	/*
+	 * We allocated the shost for the first time. Before it was NULL,
+	 * and so we deferred all updates in the xconf- and xport-data
+	 * handlers. We need to make up for that now, and make all the updates
+	 * that would have been done before.
+	 *
+	 * We can be sure that xconf- and xport-data succeeded, because
+	 * otherwise this function is not called. But they might have been
+	 * incomplete.
+	 */
+
+	spin_lock_irqsave(&config_data->header.access_lock, flags);
+	zfcp_scsi_shost_update_config_data(adapter, &config_data->data,
+					   !!config_data->header.incomplete);
+	spin_unlock_irqrestore(&config_data->header.access_lock, flags);
+
+	if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
+		spin_lock_irqsave(&port_data->header.access_lock, flags);
+		zfcp_scsi_shost_update_port_data(adapter, &port_data->data);
+		spin_unlock_irqrestore(&port_data->header.access_lock, flags);
+	}
+
+	/*
+	 * There is a remote possibility that the 'Exchange Port Data' request
+	 * reports a different connectivity status than 'Exchange Config Data'.
+	 * But any change to the connectivity status of the local optic that
+	 * happens after the initial xconf request is expected to be reported
+	 * to us, as soon as we post Status Read Buffers to the FCP channel
+	 * firmware after this function. So any resulting inconsistency will
+	 * only be momentary.
+	 */
+	if (config_data->header.incomplete)
+		zfcp_fsf_fc_host_link_down(adapter);
+
+	return ZFCP_ERP_SUCCEEDED;
+}
+
 static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf(
 	struct zfcp_erp_action *act)
 {
@@ -813,6 +867,10 @@ static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf(
 	if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED)
 		return ZFCP_ERP_FAILED;
 
+	if (zfcp_erp_adapter_strategy_alloc_shost(act->adapter) ==
+	    ZFCP_ERP_FAILED)
+		return ZFCP_ERP_FAILED;
+
 	zfcp_erp_adapter_strategy_open_ptp_port(act->adapter);
 
 	if (mempool_resize(act->adapter->pool.sr_data,
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 5dc9bdc5803f..3ef5d74331c3 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -135,6 +135,7 @@ extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
 			     struct zfcp_fsf_ct_els *, unsigned int);
 extern int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *);
 extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
+extern void zfcp_fsf_fc_host_link_down(struct zfcp_adapter *adapter);
 extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev,
 						   u8 tm_flags);
 extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 8c4b690e329e..c795f22249d8 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -120,7 +120,7 @@ static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
 	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
-static void zfcp_fsf_fc_host_link_down(struct zfcp_adapter *adapter)
+void zfcp_fsf_fc_host_link_down(struct zfcp_adapter *adapter)
 {
 	struct Scsi_Host *shost = adapter->scsi_host;
 
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index f98e4015a0ed..d58bf79892f2 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -451,26 +451,39 @@ static struct scsi_host_template zfcp_scsi_host_template = {
 };
 
 /**
- * zfcp_scsi_adapter_register - Register SCSI and FC host with SCSI midlayer
+ * zfcp_scsi_adapter_register() - Allocate and register SCSI and FC host with
+ *				  SCSI midlayer
  * @adapter: The zfcp adapter to register with the SCSI midlayer
+ *
+ * Allocates the SCSI host object for the given adapter, sets basic properties
+ * (such as the transport template, QDIO limits, ...), and registers it with
+ * the midlayer.
+ *
+ * During registration with the midlayer the corresponding FC host object for
+ * the referenced transport class is also implicitely allocated.
+ *
+ * Upon success adapter->scsi_host is set, and upon failure it remains NULL. If
+ * adapter->scsi_host is already set, nothing is done.
+ *
+ * Return:
+ * * 0	     - Allocation and registration was successful
+ * * -EEXIST - SCSI and FC host did already exist, nothing was done, nothing
+ *	       was changed
+ * * -EIO    - Allocation or registration failed
  */
 int zfcp_scsi_adapter_register(struct zfcp_adapter *adapter)
 {
 	struct ccw_dev_id dev_id;
 
 	if (adapter->scsi_host)
-		return 0;
+		return -EEXIST;
 
 	ccw_device_get_id(adapter->ccw_device, &dev_id);
 	/* register adapter as SCSI host with mid layer of SCSI stack */
 	adapter->scsi_host = scsi_host_alloc(&zfcp_scsi_host_template,
 					     sizeof (struct zfcp_adapter *));
-	if (!adapter->scsi_host) {
-		dev_err(&adapter->ccw_device->dev,
-			"Registering the FCP device with the "
-			"SCSI stack failed\n");
-		return -EIO;
-	}
+	if (!adapter->scsi_host)
+		goto err_out;
 
 	/* tell the SCSI stack some characteristics of this adapter */
 	adapter->scsi_host->max_id = 511;
@@ -480,14 +493,23 @@ int zfcp_scsi_adapter_register(struct zfcp_adapter *adapter)
 	adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */
 	adapter->scsi_host->transportt = zfcp_scsi_transport_template;
 
+	/* make all basic properties known at registration time */
+	zfcp_qdio_shost_update(adapter, adapter->qdio);
+	zfcp_scsi_set_prot(adapter);
+
 	adapter->scsi_host->hostdata[0] = (unsigned long) adapter;
 
 	if (scsi_add_host(adapter->scsi_host, &adapter->ccw_device->dev)) {
 		scsi_host_put(adapter->scsi_host);
-		return -EIO;
+		goto err_out;
 	}
 
 	return 0;
+err_out:
+	adapter->scsi_host = NULL;
+	dev_err(&adapter->ccw_device->dev,
+		"Registering the FCP device with the SCSI stack failed\n");
+	return -EIO;
 }
 
 /**
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set
  2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
                   ` (7 preceding siblings ...)
  2020-05-08 17:23 ` [PATCH 8/8] zfcp: move allocation of the shost object to after xconf- and xport-data Benjamin Block
@ 2020-05-12  3:28 ` Martin K. Petersen
  2020-05-12  9:27     ` Benjamin Block
  8 siblings, 1 reply; 12+ messages in thread
From: Martin K. Petersen @ 2020-05-12  3:28 UTC (permalink / raw)
  To: James E.J. Bottomley, Benjamin Block
  Cc: Martin K . Petersen, Steffen Maier, linux-s390, Fedor Loshakov,
	linux-scsi, Vasily Gorbik, Christian Borntraeger, Heiko Carstens,
	Julian Wiedmann

On Fri, 8 May 2020 19:23:27 +0200, Benjamin Block wrote:

> some time ago we noticed - Fedor did - that our DIV and DIX support in
> zfcp broke at some point. I tracked that down to a commit made for v5.4
> (737eb78e82d5), but we didn't notice it back than, because our CI
> doesn't currently run with either DIV, nor DIX enabled (time allowing
> this is something we want to improve so we catch stuff like this
> earlier). It also turned out that the commit in v5.4 was not really the
> root-cause, and was only making the problem visible more easy.
> 
> [...]

Applied to 5.8/scsi-queue, thanks!

[1/8] scsi: zfcp: Move shost modification after QDIO (re-)open into fenced function
      https://git.kernel.org/mkp/scsi/c/978857c7e367
[2/8] scsi: zfcp: Move shost updates during xconfig data handling into fenced function
      https://git.kernel.org/mkp/scsi/c/bd1684817d7d
[3/8] scsi: zfcp: Move fc_host updates during xport data handling into fenced function
      https://git.kernel.org/mkp/scsi/c/52e61fde5ec9
[4/8] scsi: zfcp: Fence fc_host updates during link-down handling
      https://git.kernel.org/mkp/scsi/c/990486f3a850
[5/8] scsi: zfcp: Move p-t-p port allocation to after xport data
      https://git.kernel.org/mkp/scsi/c/ac007adc4d2d
[6/8] scsi: zfcp: Fence adapter status propagation for common statuses
      https://git.kernel.org/mkp/scsi/c/971f2abb4ca4
[7/8] scsi: zfcp: Fence early sysfs interfaces for accesses of shost objects
      https://git.kernel.org/mkp/scsi/c/71159b6ecb06
[8/8] scsi: zfcp: Move allocation of the shost object to after xconf- and xport-data
      https://git.kernel.org/mkp/scsi/c/d0dff2ac98dd

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set
  2020-05-12  3:28 ` [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Martin K. Petersen
@ 2020-05-12  9:27     ` Benjamin Block
  0 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-12  9:27 UTC (permalink / raw)
  To: Martin K. Petersen
  Cc: James E.J. Bottomley, Steffen Maier, linux-s390, Fedor Loshakov,
	linux-scsi, Vasily Gorbik, Christian Borntraeger, Heiko Carstens,
	Julian Wiedmann

On Mon, May 11, 2020 at 11:28:26PM -0400, Martin K. Petersen wrote:
> On Fri, 8 May 2020 19:23:27 +0200, Benjamin Block wrote:
> 
> > some time ago we noticed - Fedor did - that our DIV and DIX support in
> > zfcp broke at some point. I tracked that down to a commit made for v5.4
> > (737eb78e82d5), but we didn't notice it back than, because our CI
> > doesn't currently run with either DIV, nor DIX enabled (time allowing
> > this is something we want to improve so we catch stuff like this
> > earlier). It also turned out that the commit in v5.4 was not really the
> > root-cause, and was only making the problem visible more easy.
> > 
> > [...]
> 
> Applied to 5.8/scsi-queue, thanks!
> 

Thanks Martin!

-- 
Best Regards, Benjamin Block  / Linux on IBM Z Kernel Development / IBM Systems
IBM Deutschland Research & Development GmbH    /    https://www.ibm.com/privacy
Vorsitz. AufsR.: Gregor Pillen         /        Gesch�ftsf�hrung: Dirk Wittkopp
Sitz der Gesellschaft: B�blingen / Registergericht: AmtsG Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set
@ 2020-05-12  9:27     ` Benjamin Block
  0 siblings, 0 replies; 12+ messages in thread
From: Benjamin Block @ 2020-05-12  9:27 UTC (permalink / raw)
  To: Martin K. Petersen
  Cc: James E.J. Bottomley, Steffen Maier, linux-s390, Fedor Loshakov,
	linux-scsi, Vasily Gorbik, Christian Borntraeger, Heiko Carstens,
	Julian Wiedmann

On Mon, May 11, 2020 at 11:28:26PM -0400, Martin K. Petersen wrote:
> On Fri, 8 May 2020 19:23:27 +0200, Benjamin Block wrote:
> 
> > some time ago we noticed - Fedor did - that our DIV and DIX support in
> > zfcp broke at some point. I tracked that down to a commit made for v5.4
> > (737eb78e82d5), but we didn't notice it back than, because our CI
> > doesn't currently run with either DIV, nor DIX enabled (time allowing
> > this is something we want to improve so we catch stuff like this
> > earlier). It also turned out that the commit in v5.4 was not really the
> > root-cause, and was only making the problem visible more easy.
> > 
> > [...]
> 
> Applied to 5.8/scsi-queue, thanks!
> 

Thanks Martin!

-- 
Best Regards, Benjamin Block  / Linux on IBM Z Kernel Development / IBM Systems
IBM Deutschland Research & Development GmbH    /    https://www.ibm.com/privacy
Vorsitz. AufsR.: Gregor Pillen         /        Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen / Registergericht: AmtsG Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-05-12  9:28 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-08 17:23 [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Benjamin Block
2020-05-08 17:23 ` [PATCH 1/8] zfcp: move shost modification after QDIO (re-)open into fenced function Benjamin Block
2020-05-08 17:23 ` [PATCH 2/8] zfcp: move shost updates during xconfig data handling " Benjamin Block
2020-05-08 17:23 ` [PATCH 3/8] zfcp: move fc_host updates during xport " Benjamin Block
2020-05-08 17:23 ` [PATCH 4/8] zfcp: fence fc_host updates during link-down handling Benjamin Block
2020-05-08 17:23 ` [PATCH 5/8] zfcp: move p-t-p port allocation to after xport data Benjamin Block
2020-05-08 17:23 ` [PATCH 6/8] zfcp: fence adapter status propagation for common statuses Benjamin Block
2020-05-08 17:23 ` [PATCH 7/8] zfcp: fence early sysfs interfaces for accesses of shost objects Benjamin Block
2020-05-08 17:23 ` [PATCH 8/8] zfcp: move allocation of the shost object to after xconf- and xport-data Benjamin Block
2020-05-12  3:28 ` [PATCH 0/8] zfcp: fix DIF/DIX support with scsi-mq host-wide tag-set Martin K. Petersen
2020-05-12  9:27   ` Benjamin Block
2020-05-12  9:27     ` Benjamin Block

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.