Re: [PATCH 1/1] scsi: storvsc: Avoid allocating memory for temp cpumasks

2018-05-17 Thread Stephen Hemminger
On Thu, 17 May 2018 14:07:40 -0700
Michael Kelley  wrote:

> Current code allocates 240 Kbytes (in typical configs) for
> each synthetic SCSI controller to use as temp cpumask variables.
> Recode to avoid needing the temp cpumask variables and remove the
> memory allocation.
> 
> Signed-off-by: Michael Kelley 

Acked-by: Stephen Hemminger 


[PATCH 1/1] scsi: storvsc: Avoid allocating memory for temp cpumasks

2018-05-17 Thread Michael Kelley
Current code allocates 240 Kbytes (in typical configs) for
each synthetic SCSI controller to use as temp cpumask variables.
Recode to avoid needing the temp cpumask variables and remove the
memory allocation.

Signed-off-by: Michael Kelley 
---

This patch is for the 4.18/scsi-queue branch and improves on commit
2217a47de42f on April 20, 2018.

---
 drivers/scsi/storvsc_drv.c | 50 ++
 1 file changed, 19 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index d3897c4..a667119 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -474,13 +474,6 @@ struct storvsc_device {
 * Mask of CPUs bound to subchannels.
 */
struct cpumask alloced_cpus;
-   /*
-* Pre-allocated struct cpumask for each hardware queue.
-* struct cpumask is used by selecting out-going channels. It is a
-* big structure, default to 1024k bytes when CONFIG_MAXSMP=y.
-* Pre-allocate it to avoid allocation on the kernel stack.
-*/
-   struct cpumask *cpumask_chns;
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
@@ -885,13 +878,6 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
if (stor_device->stor_chns == NULL)
return -ENOMEM;
 
-   stor_device->cpumask_chns = kcalloc(num_possible_cpus(),
-   sizeof(struct cpumask), GFP_KERNEL);
-   if (stor_device->cpumask_chns == NULL) {
-   kfree(stor_device->stor_chns);
-   return -ENOMEM;
-   }
-
stor_device->stor_chns[device->channel->target_cpu] = device->channel;
cpumask_set_cpu(device->channel->target_cpu,
_device->alloced_cpus);
@@ -1252,7 +1238,6 @@ static int storvsc_dev_remove(struct hv_device *device)
vmbus_close(device->channel);
 
kfree(stor_device->stor_chns);
-   kfree(stor_device->cpumask_chns);
kfree(stor_device);
return 0;
 }
@@ -1262,7 +1247,7 @@ static struct vmbus_channel *get_og_chn(struct 
storvsc_device *stor_device,
 {
u16 slot = 0;
u16 hash_qnum;
-   struct cpumask *alloced_mask = _device->cpumask_chns[q_num];
+   const struct cpumask *node_mask;
int num_channels, tgt_cpu;
 
if (stor_device->num_sc == 0)
@@ -1278,10 +1263,13 @@ static struct vmbus_channel *get_og_chn(struct 
storvsc_device *stor_device,
 * III. Mapping is persistent.
 */
 
-   cpumask_and(alloced_mask, _device->alloced_cpus,
-   cpumask_of_node(cpu_to_node(q_num)));
+   node_mask = cpumask_of_node(cpu_to_node(q_num));
 
-   num_channels = cpumask_weight(alloced_mask);
+   num_channels = 0;
+   for_each_cpu(tgt_cpu, _device->alloced_cpus) {
+   if (cpumask_test_cpu(tgt_cpu, node_mask))
+   num_channels++;
+   }
if (num_channels == 0)
return stor_device->device->channel;
 
@@ -1289,7 +1277,9 @@ static struct vmbus_channel *get_og_chn(struct 
storvsc_device *stor_device,
while (hash_qnum >= num_channels)
hash_qnum -= num_channels;
 
-   for_each_cpu(tgt_cpu, alloced_mask) {
+   for_each_cpu(tgt_cpu, _device->alloced_cpus) {
+   if (!cpumask_test_cpu(tgt_cpu, node_mask))
+   continue;
if (slot == hash_qnum)
break;
slot++;
@@ -1308,7 +1298,7 @@ static int storvsc_do_io(struct hv_device *device,
struct vstor_packet *vstor_packet;
struct vmbus_channel *outgoing_channel, *channel;
int ret = 0;
-   struct cpumask *alloced_mask;
+   const struct cpumask *node_mask;
int tgt_cpu;
 
vstor_packet = >vstor_packet;
@@ -1329,11 +1319,11 @@ static int storvsc_do_io(struct hv_device *device,
 * Ideally, we want to pick a different channel if
 * available on the same NUMA node.
 */
-   alloced_mask = _device->cpumask_chns[q_num];
-   cpumask_and(alloced_mask, _device->alloced_cpus,
-   cpumask_of_node(cpu_to_node(q_num)));
-
-   for_each_cpu_wrap(tgt_cpu, alloced_mask, q_num + 1) {
+   node_mask = cpumask_of_node(cpu_to_node(q_num));
+   for_each_cpu_wrap(tgt_cpu,
+_device->alloced_cpus, q_num + 1) {
+   if (!cpumask_test_cpu(tgt_cpu, node_mask))
+   continue;
if (tgt_cpu == q_num)
continue;
channel = stor_device->stor_chns[tgt_cpu];
@@ 

Re: [PATCH 11/40] ipv6/flowlabel: simplify pid namespace lookup

2018-05-17 Thread Eric W. Biederman
Christoph Hellwig  writes:

> On Thu, May 17, 2018 at 12:28:01AM -0500, Eric W. Biederman wrote:
>> > struct pid_namespace *proc_pid_namespace(struct inode *inode)
>> > {
>> >// maybe warn on for s_magic not on procfs??
>> >return inode->i_sb->s_fs_info;
>> > }
>> 
>> That should work.  Ideally out of line for the proc_fs.h version.
>> Basically it should be a cousin of PDE_DATA.
>
> The version in Al's tree is inline and without the warning as
> I didn't want to drag in the magic.h include.  Please look at it for
> additional comments, I can send incremental fixups if needed.

Sounds good.

Eric



[PATCH 08/25] zfcp: decouple SCSI traces for scsi_eh / TMF from scsi_cmnd

2018-05-17 Thread Steffen Maier
The SCSI command pointer passed to scsi_eh callbacks is just one arbitrary
command of potentially many that are in the eh queue to be processed.
The command is only used to indirectly pass the TMF scope in terms of
SCSI ID/target and SCSI LUN for LUN reset.

Hence, zfcp had filled in SCSI trace record fields which do not really
belong to the TMF. This was confusing.

Therefore, refactor the TMF tracing to work without SCSI command.
Since the FCP channel always requires a valid LUN handle,
we use SCSI device as common context for any TMF (even target reset).
To make it even clearer, we set all bits to 1 for the fields, which do
not belong to the TMF, to indicate that these fields are invalid.

The old zfcp_dbf_scsi() became zfcp_dbf_scsi_common() to now handle both
SCSI commands and TMFs. The old argument scsi_cmnd is now optional and
can be NULL with TMFs. The new argument scsi_device is mandatory to carry
context, as well as SCSI ID/target and SCSI LUN in case of TMFs.

New example trace record formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : SCSI
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1
Tag: [lt]r_
Request ID : 0x  ID of FSF FCP request with TM flag
 For cases without FSF request: 0x0 for none (invalid)
SCSI ID: 0xSCSI ID/target denoting scope
SCSI LUN   : 0x   SCSI LUN denoting scope
SCSI LUN high  : 0x  SCSI LUN denoting scope
SCSI result: 0x none (invalid)
SCSI retries   : 0xff   none (invalid)
SCSI allowed   : 0xff   none (invalid)
SCSI scribble  : 0x none (invalid)
SCSI opcode:    none (invalid)
FCP rsp inf cod: 0x00   FCP_RSP info code of TMF
FCP rsp IU :   0100  ext FCP_RSP IU
  0008   ext FCP_RSP IU
FCP rsp IU len : 32  FCP_RSP IU length
Payload time   : ...
FCP rsp IU all :   0100  full FCP_RSP IU
  0008   full FCP_RSP IU

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---

Notes:
Changes since RFC:

For consistency, renamed from
"zfcp: drop unsuitable scsi_cmnd usage from SCSI traces for scsi_eh / TMF".
Since the FCP channel always requires a valid LUN handle,
we use SCSI device as common context for any TMF (even target reset)
instead of explicit SCSI ID and SCSI LUN values.
Added example trace record to commit description.

 drivers/s390/scsi/zfcp_dbf.c  | 48 ---
 drivers/s390/scsi/zfcp_dbf.h  | 21 ---
 drivers/s390/scsi/zfcp_ext.h  |  5 +++--
 drivers/s390/scsi/zfcp_scsi.c | 15 +++---
 4 files changed, 56 insertions(+), 33 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 1e5ea5e4992b..bb3373260169 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -578,16 +578,18 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req 
*fsf)
 }
 
 /**
- * zfcp_dbf_scsi - trace event for scsi commands
- * @tag: identifier for event
- * @sc: pointer to struct scsi_cmnd
- * @fsf: pointer to struct zfcp_fsf_req
+ * zfcp_dbf_scsi_common() - Common trace event helper for scsi.
+ * @tag: Identifier for event.
+ * @level: trace level of event.
+ * @sdev: Pointer to SCSI device as context for this event.
+ * @sc: Pointer to SCSI command, or NULL with task management function (TMF).
+ * @fsf: Pointer to FSF request, or NULL.
  */
-void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc,
-  struct zfcp_fsf_req *fsf)
+void zfcp_dbf_scsi_common(char *tag, int level, struct scsi_device *sdev,
+ struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
 {
struct zfcp_adapter *adapter =
-   (struct zfcp_adapter *) sc->device->host->hostdata[0];
+   (struct zfcp_adapter *) sdev->host->hostdata[0];
struct zfcp_dbf *dbf = adapter->dbf;
struct zfcp_dbf_scsi *rec = >scsi_buf;
struct fcp_resp_with_ext *fcp_rsp;
@@ -599,16 +601,28 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd 
*sc,
 
memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
rec->id = ZFCP_DBF_SCSI_CMND;
-   rec->scsi_result = sc->result;
-   rec->scsi_retries = sc->retries;
-   rec->scsi_allowed = sc->allowed;
-   rec->scsi_id = sc->device->id;
-   rec->scsi_lun = (u32)sc->device->lun;
-   rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32);
-   rec->host_scribble = (unsigned long)sc->host_scribble;
-
-   memcpy(rec->scsi_opcode, sc->cmnd,
-

[PATCH 25/25] zfcp: enhance comments on fc_link_speed and supported_speed

2018-05-17 Thread Steffen Maier
From: Jens Remus 

The comment on fsf_qtcb_bottom_port.supported_speed did read as if the
field can only assume one of two possible values (i.e. 0x1 for 1 GBit/s or
0x2 for 2 GBit/s). This is not true for two reasons: first it is a flag
field and can thus assume any combination and second there are meanwhile
more speeds.

Clarify comment on fsf_qtcb_bottom_port.supported_speed and add a comment
to fsf_qtcb_bottom_config.fc_link_speed.

Signed-off-by: Jens Remus 
Reviewed-by: Steffen Maier 
Reviewed-by: Fedor Loshakov 
Acked-by: Benjamin Block 
Acked-by: Hendrik Brueckner 
Signed-off-by: Steffen Maier 
---
 drivers/s390/scsi/zfcp_fsf.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index 4baca67aba6d..535628b92f0a 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -4,7 +4,7 @@
  *
  * Interface to the FSF support functions.
  *
- * Copyright IBM Corp. 2002, 2017
+ * Copyright IBM Corp. 2002, 2018
  */
 
 #ifndef FSF_H
@@ -356,7 +356,7 @@ struct fsf_qtcb_bottom_config {
u32 adapter_features;
u32 connection_features;
u32 fc_topology;
-   u32 fc_link_speed;
+   u32 fc_link_speed;  /* one of ZFCP_FSF_PORTSPEED_* */
u32 adapter_type;
u8 res0;
u8 peer_d_id[3];
@@ -382,7 +382,7 @@ struct fsf_qtcb_bottom_port {
u32 class_of_service;   /* should be 0x0006 for class 2 and 3 */
u8 supported_fc4_types[32]; /* should be 0x0100 for scsi fcp */
u8 active_fc4_types[32];
-   u32 supported_speed;/* 0x0001 for 1 GBit/s or 0x0002 for 2 GBit/s */
+   u32 supported_speed;/* any combination of ZFCP_FSF_PORTSPEED_* */
u32 maximum_frame_size; /* fixed value of 2112 */
u64 seconds_since_last_reset;
u64 tx_frames;
-- 
2.16.3



[PATCH 23/25] zfcp: assert that the ERP lock is held when tracing a recovery trigger

2018-05-17 Thread Steffen Maier
From: Jens Remus 

Otherwise iterating with list_for_each() over the adapter->erp_ready_head
and adapter->erp_running_head lists can lead to an infinite loop. See
commit "zfcp: fix infinite iteration on erp_ready_head list".

The run-time check is only performed for debug kernels which have the
kernel lock validator enabled. Following is an example of the warning that
is reported, if the ERP lock is not held when calling zfcp_dbf_rec_trig():

WARNING: CPU: 0 PID: 604 at drivers/s390/scsi/zfcp_dbf.c:288 
zfcp_dbf_rec_trig+0x172/0x188
Modules linked in: ...
CPU: 0 PID: 604 Comm: kworker/u128:3 Not tainted 4.16.0-... #1
Hardware name: IBM 2964 N96 702 (z/VM 6.4.0)
Workqueue: zfcp_q_0.0.1906 zfcp_scsi_rport_work
Krnl PSW : 330fdbf9 367e9728 (zfcp_dbf_rec_trig+0x172/0x188)
   R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:3 PM:0 RI:0 EA:3
Krnl GPRS: c57a5d99 32882000  6cc82740
   009d09d6  00ff 
    00e1b5fe 6de01d38 76130958
   6cc82548 6de01a98 009d09d6 6a6d3c80
Krnl Code: 009d0ad2: eb7ff0b80004lmg%r7,%r15,184(%r15)
   009d0ad8: c0f4000d7dd0brcl   15,b80678
  #009d0ade: a7f40001brc15,9d0ae0
  >009d0ae2: a7f4ff7dbrc15,9d09dc
   009d0ae6: e340f0f4lg %r4,240(%r15)
   009d0aec: eb7ff0b80004lmg%r7,%r15,184(%r15)
   009d0af2: 07f4bcr15,%r4
   009d0af4: 0707bcr0,%r7
Call Trace:
([<009d09d6>] zfcp_dbf_rec_trig+0x66/0x188)
 [<009dd740>] zfcp_scsi_rport_work+0x98/0x190
 [<00169b34>] process_one_work+0x3d4/0x6f8
 [<0016a08a>] worker_thread+0x232/0x418
 [<0017219e>] kthread+0x166/0x178
 [<00b815ea>] kernel_thread_starter+0x6/0xc
 [<00b815e4>] kernel_thread_starter+0x0/0xc
2 locks held by kworker/u128:3/604:
 #0:  ((wq_completion)name){+.+.}, at: [<82af1024>] 
process_one_work+0x1dc/0x6f8
 #1:  ((work_completion)(>rport_work)){+.+.}, at: [<82af1024>] 
process_one_work+0x1dc/0x6f8
Last Breaking-Event-Address:
 [<009d0ade>] zfcp_dbf_rec_trig+0x16e/0x188
---[ end trace b2f4020572e2c124 ]---

Suggested-by: Steffen Maier 
Signed-off-by: Jens Remus 
Reviewed-by: Benjamin Block 
Reviewed-by: Steffen Maier 
Signed-off-by: Steffen Maier 
---
 drivers/s390/scsi/zfcp_dbf.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index bb3373260169..781141bf2c28 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -285,6 +285,8 @@ void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter 
*adapter,
struct list_head *entry;
unsigned long flags;
 
+   lockdep_assert_held(>erp_lock);
+
if (unlikely(!debug_level_enabled(dbf->rec, level)))
return;
 
-- 
2.16.3



[PATCH 22/25] zfcp: cleanup indentation for posting FC events

2018-05-17 Thread Steffen Maier
I just happened to see the function header indentation of
zfcp_fc_enqueue_event() and I picked some more from checkpatch:

$ checkpatch.pl --strict -f drivers/s390/scsi/zfcp_fc.c
...
CHECK: Alignment should match open parenthesis
 #113: FILE: drivers/s390/scsi/zfcp_fc.c:113:
+   fc_host_post_event(adapter->scsi_host, fc_get_event_number(),
+   event->code, event->data);

CHECK: Blank lines aren't necessary before a close brace '}'
 #118: FILE: drivers/s390/scsi/zfcp_fc.c:118:
+
+}
...

The change complements v2.6.36 commit 2d1e547f7523 ("[SCSI] zfcp: Post
events through FC transport class").

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_fc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 54186943896b..f6c415d6ef48 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -111,11 +111,10 @@ void zfcp_fc_post_event(struct work_struct *work)
 
list_for_each_entry_safe(event, tmp, _lh, list) {
fc_host_post_event(adapter->scsi_host, fc_get_event_number(),
-   event->code, event->data);
+  event->code, event->data);
list_del(>list);
kfree(event);
}
-
 }
 
 /**
@@ -126,7 +125,7 @@ void zfcp_fc_post_event(struct work_struct *work)
  * @event_data: The event data (e.g. n_port page in case of els)
  */
 void zfcp_fc_enqueue_event(struct zfcp_adapter *adapter,
-   enum fc_host_event_code event_code, u32 event_data)
+  enum fc_host_event_code event_code, u32 event_data)
 {
struct zfcp_fc_event *event;
 
-- 
2.16.3



[PATCH 21/25] zfcp: support SCSI_ADAPTER_RESET via scsi_host sysfs attribute host_reset

2018-05-17 Thread Steffen Maier
Make use of feature introduced with v3.2 commit 294436914454
("[SCSI] scsi: Added support for adapter and firmware reset").
The common code interface was introduced for commit 95d31262b3c1
("[SCSI] qla4xxx: Added support for adapter and firmware reset").

$ echo adapter > /sys/class/scsi_host/host/host_reset

Example trace record formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : REC
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1  ZFCP_DBF_REC_TRIG
Tag: scshr_ySCSI sysfs host_reset yes
LUN: 0x none (invalid)
WWPN   : 0x none (invalid)
D_ID   : 0x none (invalid)
Adapter status : 0x4500050b
Port status: 0x none (invalid)
LUN status : 0x none (invalid)
Ready count: 0x0001
Running count  : 0x
ERP want   : 0x04   ZFCP_ERP_ACTION_REOPEN_ADAPTER
ERP need   : 0x04   ZFCP_ERP_ACTION_REOPEN_ADAPTER

This is the common code equivalent to the zfcp-specific
_attr_adapter_failed.attr in zfcp_sysfs_adapter_attrs.attrs[]:

$ echo 0 > /sys/bus/ccw/drivers/zfcp//failed

The unsupported case returns EOPNOTSUPP:

$ echo firmware > /sys/class/scsi_host/host/host_reset
-bash: echo: write error: Operation not supported

Example trace record formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : SCSI
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1
Tag: scshr_nSCSI sysfs host_reset no
Request ID : 0x none (invalid)
SCSI ID: 0x none (invalid)
SCSI LUN   : 0x none (invalid)
SCSI LUN high  : 0x none (invalid)
SCSI result: 0xffa1 -EOPNOTSUPP==-95
SCSI retries   : 0xff   none (invalid)
SCSI allowed   : 0xff   none (invalid)
SCSI scribble  : 0x none (invalid)
SCSI opcode:    none (invalid)
FCP rsp inf cod: 0xff   none (invalid)
FCP rsp IU :    none (invalid)
  

For any other invalid value, common code returns EINVAL without invoking
our callback:

$ echo foo > /sys/class/scsi_host/host/host_reset
-bash: echo: write error: Invalid argument

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c   | 11 +++
 drivers/s390/scsi/zfcp_ext.h   |  1 +
 drivers/s390/scsi/zfcp_scsi.c  | 26 ++
 drivers/s390/scsi/zfcp_sysfs.c |  5 +
 4 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 2968d2f57788..e7e6b63905e2 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1691,3 +1691,14 @@ void zfcp_erp_clear_lun_status(struct scsi_device *sdev, 
u32 mask)
atomic_set(_sdev->erp_counter, 0);
 }
 
+/**
+ * zfcp_erp_adapter_reset_sync() - Really reopen adapter and wait.
+ * @adapter: Pointer to zfcp_adapter to reopen.
+ * @id: Trace tag string of length %ZFCP_DBF_TAG_LEN.
+ */
+void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter, char *id)
+{
+   zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
+   zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, id);
+   zfcp_erp_wait(adapter);
+}
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index ad7c28ffd49f..f3b55cce748a 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -76,6 +76,7 @@ extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
 extern void zfcp_erp_wait(struct zfcp_adapter *);
 extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
 extern void zfcp_erp_timeout_handler(struct timer_list *t);
+extern void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter, char 
*id);
 
 /* zfcp_fc.c */
 extern struct kmem_cache *zfcp_fc_req_cache;
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index f69ef78ea930..9a01f583e562 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -372,6 +372,31 @@ static int zfcp_scsi_eh_host_reset_handler(struct 
scsi_cmnd *scpnt)
return ret;
 }
 
+/**
+ * zfcp_scsi_sysfs_host_reset() - Support scsi_host sysfs attribute host_reset.
+ * @shost: Pointer to Scsi_Host to perform action on.
+ * 

[PATCH 24/25] zfcp: add port speed capabilities

2018-05-17 Thread Steffen Maier
From: Jens Remus 

Add port speed capabilities as defined in FC-LS RPSC ELS that have a
counterpart FC_PORTSPEED_* defined in scsi/scsi_transport_fc.h.

Suggested-by: Steffen Maier 
Signed-off-by: Jens Remus 
Reviewed-by: Steffen Maier 
Reviewed-by: Fedor Loshakov 
Acked-by: Hendrik Brueckner 
Acked-by: Benjamin Block 
Signed-off-by: Steffen Maier 
---
 drivers/s390/scsi/zfcp_fsf.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 049fdd968130..3c86e27f094d 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -4,7 +4,7 @@
  *
  * Implementation of FSF commands.
  *
- * Copyright IBM Corp. 2002, 2017
+ * Copyright IBM Corp. 2002, 2018
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -437,6 +437,9 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
 #define ZFCP_FSF_PORTSPEED_10GBIT  (1 <<  3)
 #define ZFCP_FSF_PORTSPEED_8GBIT   (1 <<  4)
 #define ZFCP_FSF_PORTSPEED_16GBIT  (1 <<  5)
+#define ZFCP_FSF_PORTSPEED_32GBIT  (1 <<  6)
+#define ZFCP_FSF_PORTSPEED_64GBIT  (1 <<  7)
+#define ZFCP_FSF_PORTSPEED_128GBIT (1 <<  8)
 #define ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED (1 << 15)
 
 static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed)
@@ -454,6 +457,12 @@ static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed)
fdmi_speed |= FC_PORTSPEED_8GBIT;
if (fsf_speed & ZFCP_FSF_PORTSPEED_16GBIT)
fdmi_speed |= FC_PORTSPEED_16GBIT;
+   if (fsf_speed & ZFCP_FSF_PORTSPEED_32GBIT)
+   fdmi_speed |= FC_PORTSPEED_32GBIT;
+   if (fsf_speed & ZFCP_FSF_PORTSPEED_64GBIT)
+   fdmi_speed |= FC_PORTSPEED_64GBIT;
+   if (fsf_speed & ZFCP_FSF_PORTSPEED_128GBIT)
+   fdmi_speed |= FC_PORTSPEED_128GBIT;
if (fsf_speed & ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED)
fdmi_speed |= FC_PORTSPEED_NOT_NEGOTIATED;
return fdmi_speed;
-- 
2.16.3



[PATCH 18/25] zfcp: zfcp_erp_action_exists() does only check for running

2018-05-17 Thread Steffen Maier
Simplify its signature to return boolean and rename it to
zfcp_erp_action_is_running() to indicate its actual unmodified semantics.
It has always been used like this since v2.6.0 history commit ea127f975424
("[PATCH] s390 (7/7): zfcp host adapter.").

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c | 14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index b5ca484d5d5f..245621769c26 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -57,10 +57,6 @@ enum zfcp_erp_act_type {
ZFCP_ERP_ACTION_FAILED = 0xe0,
 };
 
-enum zfcp_erp_act_state {
-   ZFCP_ERP_ACTION_RUNNING = 1,
-};
-
 enum zfcp_erp_act_result {
ZFCP_ERP_SUCCEEDED = 0,
ZFCP_ERP_FAILED= 1,
@@ -76,14 +72,14 @@ static void zfcp_erp_adapter_block(struct zfcp_adapter 
*adapter, int mask)
   ZFCP_STATUS_COMMON_UNBLOCKED | mask);
 }
 
-static int zfcp_erp_action_exists(struct zfcp_erp_action *act)
+static bool zfcp_erp_action_is_running(struct zfcp_erp_action *act)
 {
struct zfcp_erp_action *curr_act;
 
list_for_each_entry(curr_act, >adapter->erp_running_head, list)
if (act == curr_act)
-   return ZFCP_ERP_ACTION_RUNNING;
-   return 0;
+   return true;
+   return false;
 }
 
 static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
@@ -99,7 +95,7 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
 static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act)
 {
act->status |= ZFCP_STATUS_ERP_DISMISSED;
-   if (zfcp_erp_action_exists(act) == ZFCP_ERP_ACTION_RUNNING)
+   if (zfcp_erp_action_is_running(act))
zfcp_erp_action_ready(act);
 }
 
@@ -622,7 +618,7 @@ void zfcp_erp_notify(struct zfcp_erp_action *erp_action, 
unsigned long set_mask)
unsigned long flags;
 
write_lock_irqsave(>erp_lock, flags);
-   if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) {
+   if (zfcp_erp_action_is_running(erp_action)) {
erp_action->status |= set_mask;
zfcp_erp_action_ready(erp_action);
}
-- 
2.16.3



[PATCH 09/25] zfcp: decouple TMF response handler from scsi_cmnd

2018-05-17 Thread Steffen Maier
Originally, I planned for TMF handling to have different context data in
fsf_req->data depending on the TMF scope in fcp_cmnd->fc_tm_flags:
* scsi_device if FCP_TMF_LUN_RESET,
* zfcp_port if FCP_TMF_TGT_RESET.
However, the FCP channel requires a valid LUN handle so we now use
scsi_device as context data with any TMF for the time being.

Regular SCSI I/O FCP requests continue using scsi_cmnd as req->data.

Hence, the callers of zfcp_fsf_fcp_handler_common() must resolve req->data
and pass scsi_device as common context.
While at it, remove the detour zfcp_sdev->port->adapter and use the more
direct req->adapter as elsewhere in this function already.

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---

Notes:
Changes since RFC:

Since the FCP channel always requires a valid LUN handle,
we now use scsi_device as context data with any TMF instead of either
scsi_device for FCP_TMF_LUN_RESET or zfcp_port for FCP_TMF_TGT_RESET.

This also fixes a kernel panic due to a wrongly assigned req->data
in the previous patch version.

Added missing description on replacing zfcp_sdev->port->adapter with
req->adapter which was already in the previous patch content.
This is now the only change left in zfcp_fsf_fcp_handler_common().

 drivers/s390/scsi/zfcp_fsf.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index b12cb81ad8a2..a95070c7cad8 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2036,10 +2036,14 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req 
*req, struct scsi_cmnd *scsi)
sizeof(blktrc));
 }
 
-static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
+/**
+ * zfcp_fsf_fcp_handler_common() - FCP response handler common to I/O and TMF.
+ * @req: Pointer to FSF request.
+ * @sdev: Pointer to SCSI device as request context.
+ */
+static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req,
+   struct scsi_device *sdev)
 {
-   struct scsi_cmnd *scmnd = req->data;
-   struct scsi_device *sdev = scmnd->device;
struct zfcp_scsi_dev *zfcp_sdev;
struct fsf_qtcb_header *header = >qtcb->header;
 
@@ -2051,7 +2055,7 @@ static void zfcp_fsf_fcp_handler_common(struct 
zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_HANDLE_MISMATCH:
case FSF_PORT_HANDLE_NOT_VALID:
-   zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fssfch1");
+   zfcp_erp_adapter_reopen(req->adapter, 0, "fssfch1");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_FCPLUN_NOT_VALID:
@@ -2069,8 +2073,7 @@ static void zfcp_fsf_fcp_handler_common(struct 
zfcp_fsf_req *req)
req->qtcb->bottom.io.data_direction,
(unsigned long long)zfcp_scsi_dev_lun(sdev),
(unsigned long long)zfcp_sdev->port->wwpn);
-   zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0,
- "fssfch3");
+   zfcp_erp_adapter_shutdown(req->adapter, 0, "fssfch3");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_CMND_LENGTH_NOT_VALID:
@@ -2080,8 +2083,7 @@ static void zfcp_fsf_fcp_handler_common(struct 
zfcp_fsf_req *req)
req->qtcb->bottom.io.fcp_cmnd_length,
(unsigned long long)zfcp_scsi_dev_lun(sdev),
(unsigned long long)zfcp_sdev->port->wwpn);
-   zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0,
- "fssfch4");
+   zfcp_erp_adapter_shutdown(req->adapter, 0, "fssfch4");
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PORT_BOXED:
@@ -2120,7 +2122,7 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req 
*req)
return;
}
 
-   zfcp_fsf_fcp_handler_common(req);
+   zfcp_fsf_fcp_handler_common(req, scpnt->device);
 
if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
@@ -2297,10 +2299,11 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
 
 static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
 {
+   struct scsi_device *sdev = req->data;
struct fcp_resp_with_ext *fcp_rsp;
struct fcp_resp_rsp_info *rsp_info;
 
-   zfcp_fsf_fcp_handler_common(req);
+   zfcp_fsf_fcp_handler_common(req, sdev);
 
fcp_rsp = >qtcb->bottom.io.fcp_rsp.iu;
rsp_info = (struct fcp_resp_rsp_info *) _rsp[1];
@@ -2341,7 +2344,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct 
scsi_cmnd *scmnd,
goto out;
}
 
-   

[PATCH 16/25] zfcp: consistently use function name space prefix

2018-05-17 Thread Steffen Maier
I've been mixing up
zfcp_task_mgmt_function() [SCSI] and
zfcp_fsf_fcp_task_mgmt()  [FSF]
so often lately that I wanted to fix this.

SCSI changes complement v2.6.27 commit f76af7d7e363
("[SCSI] zfcp: Cleanup of code in zfcp_scsi.c").

While at it, also fixup the other inconsistencies elsewhere.

ERP changes complement v2.6.27 commit 287ac01acf22
("[SCSI] zfcp: Cleanup code in zfcp_erp.c") which introduced
status_change_set().

FC changes complement v2.6.32 commit 6f53a2d2ecae
("[SCSI] zfcp: Apply common naming conventions to zfcp_fc").
by renaming a leftover introduced with v2.6.27 commit cc8c282963bd
("[SCSI] zfcp: Automatically attach remote ports").

FSF changes fixup v2.6.32 commit a4623c467ff7
("[SCSI] zfcp: Improve request allocation through mempools").
which replaced zfcp_fsf_alloc_qtcb() introduced with v2.6.27
commit c41f8cbddd4e ("[SCSI] zfcp: zfcp_fsf cleanup.").

SCSI fc_host statistics were introduced with v2.6.16 commit f6cd94b126aa
("[SCSI] zfcp: transport class adaptations").

SCSI fc_host port_state was introduced with v2.6.27 commit 85a82392fe6f
("[SCSI] zfcp: Add port_state attribute to sysfs").

SCSI rport setter for dev_loss_tmo was introduced with v2.6.18
commit 338151e06608 ("[SCSI] zfcp: make use of fc_remote_port_delete when
target port is unavailable").

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c  | 11 +++
 drivers/s390/scsi/zfcp_fc.c   |  4 ++--
 drivers/s390/scsi/zfcp_fsf.c  |  7 ---
 drivers/s390/scsi/zfcp_scsi.c | 46 ++-
 4 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 69dfb328dba4..9be629607dc0 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -551,21 +551,23 @@ void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, 
char *id)
zfcp_erp_wait(adapter);
 }
 
-static int status_change_set(unsigned long mask, atomic_t *status)
+static int zfcp_erp_status_change_set(unsigned long mask, atomic_t *status)
 {
return (atomic_read(status) ^ mask) & mask;
 }
 
 static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
 {
-   if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, >status))
+   if (zfcp_erp_status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED,
+  >status))
zfcp_dbf_rec_run("eraubl1", >erp_action);
atomic_or(ZFCP_STATUS_COMMON_UNBLOCKED, >status);
 }
 
 static void zfcp_erp_port_unblock(struct zfcp_port *port)
 {
-   if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, >status))
+   if (zfcp_erp_status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED,
+  >status))
zfcp_dbf_rec_run("erpubl1", >erp_action);
atomic_or(ZFCP_STATUS_COMMON_UNBLOCKED, >status);
 }
@@ -574,7 +576,8 @@ static void zfcp_erp_lun_unblock(struct scsi_device *sdev)
 {
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
 
-   if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, _sdev->status))
+   if (zfcp_erp_status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED,
+  _sdev->status))
zfcp_dbf_rec_run("erlubl1", _to_zfcp(sdev)->erp_action);
atomic_or(ZFCP_STATUS_COMMON_UNBLOCKED, _sdev->status);
 }
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 2ad80c43f674..54186943896b 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -598,7 +598,7 @@ void zfcp_fc_test_link(struct zfcp_port *port)
put_device(>dev);
 }
 
-static struct zfcp_fc_req *zfcp_alloc_sg_env(int buf_num)
+static struct zfcp_fc_req *zfcp_fc_alloc_sg_env(int buf_num)
 {
struct zfcp_fc_req *fc_req;
 
@@ -750,7 +750,7 @@ void zfcp_fc_scan_ports(struct work_struct *work)
if (zfcp_fc_wka_port_get(>gs->ds))
return;
 
-   fc_req = zfcp_alloc_sg_env(buf_num);
+   fc_req = zfcp_fc_alloc_sg_env(buf_num);
if (!fc_req)
goto out;
 
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index d86c3bf71664..049fdd968130 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -662,7 +662,7 @@ static struct zfcp_fsf_req *zfcp_fsf_alloc(mempool_t *pool)
return req;
 }
 
-static struct fsf_qtcb *zfcp_qtcb_alloc(mempool_t *pool)
+static struct fsf_qtcb *zfcp_fsf_qtcb_alloc(mempool_t *pool)
 {
struct fsf_qtcb *qtcb;
 
@@ -701,9 +701,10 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct 
zfcp_qdio *qdio,
 
if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) {
if (likely(pool))
-   req->qtcb = zfcp_qtcb_alloc(adapter->pool.qtcb_pool);
+   req->qtcb = zfcp_fsf_qtcb_alloc(
+   adapter->pool.qtcb_pool);

[PATCH 05/25] zfcp: fix missing REC trigger trace on terminate_rport_io for ERP_FAILED

2018-05-17 Thread Steffen Maier
For problem determination we always want to see when we were invoked
on the terminate_rport_io callback whether we perform something or not.

Temporal event sequence of interest with a long fast_io_fail_tmo of 27 sec:

loose remote port

t   workqueue
[s] zfcp_q_   IRQ zfcperp
=== == === 

  0recv RSCN
   q p.test_link_work
block rport
 start fast_io_fail_tmo
send ADISC ELS
  4recv ADISC fail
   block zfcp_port
   port forced reopen
   send open port
 12recv open port fail
   q p.gid_pn_work
   zfcp_erp_wakeup
   (zfcp_erp_wait would return)
GID_PN fail

Before this point, we got a SCSI trace with tag "sctrpi1" on fast_io_fail,
e.g. with the typical 5 sec setting.

port.status |= ERP_FAILED

If fast_io_fail_tmo triggers after this point, we missed a SCSI trace.

workqueue
fc_dl_
==
 27 fc_timeout_fail_rport_io
fc_terminate_rport_io
zfcp_scsi_terminate_rport_io
zfcp_erp_port_forced_reopen
_zfcp_erp_port_forced_reopen
 if (port.status & ERP_FAILED)
  return;

Therefore, write a trace before above early return.

Example trace record formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : REC
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1  ZFCP_DBF_REC_TRIG
Tag: sctrpi1SCSI terminate rport I/O
LUN: 0x none (invalid)
WWPN   : 0x
D_ID   : 0x
Adapter status : 0x...
Port status: 0x...
LUN status : 0x none (invalid)
Ready count: 0x...
Running count  : 0x...
ERP want   : 0x03   ZFCP_ERP_ACTION_REOPEN_PORT_FORCED
ERP need   : 0xe0   ZFCP_ERP_ACTION_FAILED

Signed-off-by: Steffen Maier 
Cc:  #2.6.38+
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 3489b1bc9121..5c368cdfc455 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -42,9 +42,13 @@ enum zfcp_erp_steps {
  * @ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: Forced port recovery.
  * @ZFCP_ERP_ACTION_REOPEN_ADAPTER: Adapter recovery.
  * @ZFCP_ERP_ACTION_NONE: Eyecatcher pseudo flag to bitwise or-combine with
- *   either of the other enum values.
+ *   either of the first four enum values.
  *   Used to indicate that an ERP action could not be
  *   set up despite a detected need for some recovery.
+ * @ZFCP_ERP_ACTION_FAILED: Eyecatcher pseudo flag to bitwise or-combine with
+ * either of the first four enum values.
+ * Used to indicate that ERP not needed because
+ * the object has ZFCP_STATUS_COMMON_ERP_FAILED.
  */
 enum zfcp_erp_act_type {
ZFCP_ERP_ACTION_REOPEN_LUN = 1,
@@ -52,6 +56,7 @@ enum zfcp_erp_act_type {
ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3,
ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4,
ZFCP_ERP_ACTION_NONE   = 0xc0,
+   ZFCP_ERP_ACTION_FAILED = 0xe0,
 };
 
 enum zfcp_erp_act_state {
@@ -379,8 +384,12 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port 
*port, int clear,
zfcp_erp_port_block(port, clear);
zfcp_scsi_schedule_rport_block(port);
 
-   if (atomic_read(>status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+   if (atomic_read(>status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
+   zfcp_dbf_rec_trig(id, port->adapter, port, NULL,
+ ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
+ ZFCP_ERP_ACTION_FAILED);
return;
+   }
 
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
port->adapter, port, NULL, id, 0);
-- 
2.16.3



[PATCH 14/25] zfcp: decouple our scsi_eh callbacks from scsi_cmnd

2018-05-17 Thread Steffen Maier
Note: zfcp_scsi_eh_host_reset_handler() will be converted in a later patch.

zfcp_scsi_eh_device_reset_handler() now only depends on scsi_device.
zfcp_scsi_eh_target_reset_handler() now only depends on scsi_target.
All derive other objects from these intended callback arguments.

zfcp_scsi_eh_target_reset_handler() is special: The FCP channel requires
a valid LUN handle so we try to find ourselves a stand-in scsi_device as
suggested by Hannes Reinecke. If it cannot find a stand-in scsi device,
trace a record like the following (formatted with zfcpdbf from s390-tools):

Timestamp  : ...
Area   : SCSI
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1
Tag: tr_nosdtarget reset, no SCSI device
Request ID : 0x none (invalid)
SCSI ID: 0x SCSI ID/target denoting scope
SCSI LUN   : 0x none (invalid)
SCSI LUN high  : 0x none (invalid)
SCSI result: 0x2003 field re-used for midlayer value: FAILED
SCSI retries   : 0xff   none (invalid)
SCSI allowed   : 0xff   none (invalid)
SCSI scribble  : 0x none (invalid)
SCSI opcode:    none (invalid)
FCP rsp inf cod: 0xff   none (invalid)
FCP rsp IU :    none (invalid)
  

Actually change the signature of zfcp_task_mgmt_function() used by
zfcp_scsi_eh_device_reset_handler() & zfcp_scsi_eh_target_reset_handler().
Since it was prepared in a previous patch, we only need to delete
a local auto variable which is now the intended argument.

Suggested-by: Hannes Reinecke 
Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---

Notes:
Changes since RFC:

Since the FCP channel always requires a valid LUN handle,
we now use scsi_device as context data with any TMF instead of
zfcp_port for FCP_TMF_TGT_RESET and an optional scsi_device for
FCP_TMF_LUN_RESET.

zfcp_scsi_eh_target_reset_handler() became more involved as it needs
to find a stand-in scsi_device within the target scope as suggested by
Hannes.
Trace if we could not find a stand-in scsi_device along with
an example trace in the commit description.
Put the refcount from shost_for_each_device for the stand-in scsi_device.

NB:
zfcp_scsi_eh_host_reset_handler() will be converted in a later patch.
I need more time to resolve the proper sync with all fc_rports states
with support for FAST_IO_FAIL.

 drivers/s390/scsi/zfcp_scsi.c | 41 +
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index e0c5735cf3db..fcc832b73960 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -265,9 +265,14 @@ static void zfcp_scsi_forget_cmnds(struct zfcp_scsi_dev 
*zsdev, u8 tm_flags)
write_unlock_irqrestore(>abort_lock, flags);
 }
 
-static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
+/**
+ * zfcp_task_mgmt_function() - Synchronously send a task management function.
+ * @sdev: Pointer to SCSI device to send the task management command to.
+ * @tm_flags: Task management flags,
+ *   here we only handle %FCP_TMF_TGT_RESET or %FCP_TMF_LUN_RESET.
+ */
+static int zfcp_task_mgmt_function(struct scsi_device *sdev, u8 tm_flags)
 {
-   struct scsi_device *sdev = scpnt->device;
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
@@ -315,12 +320,40 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd 
*scpnt, u8 tm_flags)
 
 static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
 {
-   return zfcp_task_mgmt_function(scpnt, FCP_TMF_LUN_RESET);
+   struct scsi_device *sdev = scpnt->device;
+
+   return zfcp_task_mgmt_function(sdev, FCP_TMF_LUN_RESET);
 }
 
 static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
 {
-   return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
+   struct scsi_target *starget = scsi_target(scpnt->device);
+   struct fc_rport *rport = starget_to_rport(starget);
+   struct Scsi_Host *shost = rport_to_shost(rport);
+   struct scsi_device *sdev = NULL, *tmp_sdev;
+   struct zfcp_adapter *adapter =
+   (struct zfcp_adapter *)shost->hostdata[0];
+   int ret;
+
+   shost_for_each_device(tmp_sdev, shost) {
+   if (tmp_sdev->id == starget->id) {
+   sdev = tmp_sdev;
+  

[PATCH 17/25] zfcp: remove unused ERP enum values

2018-05-17 Thread Steffen Maier
All constant defines were introduced with v2.6.0 history commit
ea127f975424 ("[PATCH] s390 (7/7): zfcp host adapter.") and refactored into
enums with commit 287ac01acf22 ("[SCSI] zfcp: Cleanup code in zfcp_erp.c").

ZFCP_STATUS_ERP_DISMISSING and ZFCP_ERP_STEP_FSF_XCONFIG were never used.

v2.6.27 commit 287ac01acf22 ("[SCSI] zfcp: Cleanup code in zfcp_erp.c")
removed the use of ZFCP_ERP_ACTION_READY on refactoring
zfcp_erp_action_exists() to now only check adapter->erp_running_head
but no longer adapter->erp_ready_head. The same commit could have
changed the function return type from int to "enum zfcp_erp_act_state".
ZFCP_ERP_ACTION_READY was never used outside of zfcp_erp_action_exists().

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 9be629607dc0..b5ca484d5d5f 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -19,7 +19,6 @@
 enum zfcp_erp_act_flags {
ZFCP_STATUS_ERP_TIMEDOUT= 0x1000,
ZFCP_STATUS_ERP_CLOSE_ONLY  = 0x0100,
-   ZFCP_STATUS_ERP_DISMISSING  = 0x0010,
ZFCP_STATUS_ERP_DISMISSED   = 0x0020,
ZFCP_STATUS_ERP_LOWMEM  = 0x0040,
ZFCP_STATUS_ERP_NO_REF  = 0x0080,
@@ -27,7 +26,6 @@ enum zfcp_erp_act_flags {
 
 enum zfcp_erp_steps {
ZFCP_ERP_STEP_UNINITIALIZED = 0x,
-   ZFCP_ERP_STEP_FSF_XCONFIG   = 0x0001,
ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010,
ZFCP_ERP_STEP_PORT_CLOSING  = 0x0100,
ZFCP_ERP_STEP_PORT_OPENING  = 0x0800,
@@ -61,7 +59,6 @@ enum zfcp_erp_act_type {
 
 enum zfcp_erp_act_state {
ZFCP_ERP_ACTION_RUNNING = 1,
-   ZFCP_ERP_ACTION_READY   = 2,
 };
 
 enum zfcp_erp_act_result {
-- 
2.16.3



[PATCH 19/25] zfcp: remove unused return values of ERP trigger functions

2018-05-17 Thread Steffen Maier
Since v2.6.27 commit 553448f6c483 ("[SCSI] zfcp: Message cleanup"),
none of the callers has been interested any more.
Values were not returned consistently in all ERP trigger functions.

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c | 34 +-
 drivers/s390/scsi/zfcp_ext.h |  2 +-
 2 files changed, 14 insertions(+), 22 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 245621769c26..2968d2f57788 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -294,12 +294,12 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int 
need, u32 act_status,
return erp_action;
 }
 
-static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
-  struct zfcp_port *port,
-  struct scsi_device *sdev,
-  char *id, u32 act_status)
+static void zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
+   struct zfcp_port *port,
+   struct scsi_device *sdev,
+   char *id, u32 act_status)
 {
-   int retval = 1, need;
+   int need;
struct zfcp_erp_action *act;
 
need = zfcp_erp_handle_failed(want, adapter, port, sdev);
@@ -310,7 +310,6 @@ static int zfcp_erp_action_enqueue(int want, struct 
zfcp_adapter *adapter,
 
if (!adapter->erp_thread) {
need = ZFCP_ERP_ACTION_NONE; /* marker for trace */
-   retval = -EIO;
goto out;
}
 
@@ -327,10 +326,8 @@ static int zfcp_erp_action_enqueue(int want, struct 
zfcp_adapter *adapter,
++adapter->erp_total_count;
list_add_tail(>list, >erp_ready_head);
wake_up(>erp_ready_wq);
-   retval = 0;
  out:
zfcp_dbf_rec_trig(id, adapter, port, sdev, want, need);
-   return retval;
 }
 
 void zfcp_erp_port_forced_no_port_dbf(char *id, struct zfcp_adapter *adapter,
@@ -353,14 +350,14 @@ void zfcp_erp_port_forced_no_port_dbf(char *id, struct 
zfcp_adapter *adapter,
write_unlock_irqrestore(>erp_lock, flags);
 }
 
-static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
+static void _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
int clear_mask, char *id)
 {
zfcp_erp_adapter_block(adapter, clear_mask);
zfcp_scsi_schedule_rports_block(adapter);
 
-   return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
-  adapter, NULL, NULL, id, 0);
+   zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
+   adapter, NULL, NULL, id, 0);
 }
 
 /**
@@ -439,13 +436,13 @@ void zfcp_erp_port_forced_reopen(struct zfcp_port *port, 
int clear, char *id)
write_unlock_irqrestore(>erp_lock, flags);
 }
 
-static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
+static void _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
 {
zfcp_erp_port_block(port, clear);
zfcp_scsi_schedule_rport_block(port);
 
-   return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
-  port->adapter, port, NULL, id, 0);
+   zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
+   port->adapter, port, NULL, id, 0);
 }
 
 /**
@@ -453,20 +450,15 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, 
int clear, char *id)
  * @port: port to recover
  * @clear_mask: flags in port status to be cleared
  * @id: Id for debug trace event.
- *
- * Returns 0 if recovery has been triggered, < 0 if not.
  */
-int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
+void zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
 {
-   int retval;
unsigned long flags;
struct zfcp_adapter *adapter = port->adapter;
 
write_lock_irqsave(>erp_lock, flags);
-   retval = _zfcp_erp_port_reopen(port, clear, id);
+   _zfcp_erp_port_reopen(port, clear, id);
write_unlock_irqrestore(>erp_lock, flags);
-
-   return retval;
 }
 
 static void zfcp_erp_lun_block(struct scsi_device *sdev, int clear_mask)
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index e317c4b513c9..ad7c28ffd49f 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -63,7 +63,7 @@ extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, 
int, char *);
 extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *);
 extern void zfcp_erp_set_port_status(struct zfcp_port *, u32);
 extern void zfcp_erp_clear_port_status(struct zfcp_port *, u32);
-extern int  zfcp_erp_port_reopen(struct zfcp_port *, int, char *);
+extern void zfcp_erp_port_reopen(struct zfcp_port *port, int 

[PATCH 20/25] zfcp: explicitly support initiator in scsi_host_template

2018-05-17 Thread Steffen Maier
While the default did already correctly print "Initiator"
let's make it explicit and convert zfcp to the feature.

$ cat /sys/class/scsi_host/host0/supported_mode
Initiator

$ cat /sys/class/scsi_host/host0/active_mode
Initiator

The default worked, because not setting the field has it initialized
to zero == MODE_UNKNOWN. scsi_host_alloc() sets shost->active_mode =
MODE_INITIATOR in this case. The sysfs accessor function
show_shost_supported_mode() assumes MODE_INITIATOR in this case.
This default behavior was introduced with v2.6.24 commit 7a39ac3f25be
("[SCSI] make supported_mode default to initiator.").
The feature flag was introduced with v2.6.24 commit 5dc2b89e1242
("[SCSI] add supported_mode and active_mode attributes to the host").
So there was no release where zfcp would have shown "unknown".

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_scsi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index b4e1f1b82503..f69ef78ea930 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -401,6 +401,7 @@ static struct scsi_host_template zfcp_scsi_host_template = {
.shost_attrs = zfcp_sysfs_shost_attrs,
.sdev_attrs  = zfcp_sysfs_sdev_attrs,
.track_queue_depth   = 1,
+   .supported_mode  = MODE_INITIATOR,
 };
 
 /**
-- 
2.16.3



[PATCH 06/25] zfcp: fix missing REC trigger trace for all objects in ERP_FAILED

2018-05-17 Thread Steffen Maier
That other commit introduced an inconsistency because it would trace
on ERP_FAILED for all callers of port forced reopen triggers
(not just terminate_rport_io), but it would not trace on ERP_FAILED
for all callers of other ERP triggers such as adapter, port regular, LUN.

Therefore, generalize that other commit. zfcp_erp_action_enqueue()
already had two early outs which re-used the one zfcp_dbf_rec_trig() call.
All ERP trigger functions finally run through zfcp_erp_action_enqueue().
So move the special handling for ZFCP_STATUS_COMMON_ERP_FAILED into
zfcp_erp_action_enqueue() and add another early out with new trace marker
for pseudo ERP need in this case. This removes all early returns from
all ERP trigger functions so we always end up at zfcp_dbf_rec_trig().

Example trace record formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : REC
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1  ZFCP_DBF_REC_TRIG
Tag: ...
LUN: 0x...
WWPN   : 0x...
D_ID   : 0x...
Adapter status : 0x...
Port status: 0x...
LUN status : 0x...
Ready count: 0x...
Running count  : 0x...
ERP want   : 0x0.   ZFCP_ERP_ACTION_REOPEN_...
ERP need   : 0xe0   ZFCP_ERP_ACTION_FAILED

Signed-off-by: Steffen Maier 
Cc:  #2.6.38+
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c | 79 
 1 file changed, 51 insertions(+), 28 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 5c368cdfc455..20fe59300d0e 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -143,6 +143,49 @@ static void zfcp_erp_action_dismiss_adapter(struct 
zfcp_adapter *adapter)
}
 }
 
+static int zfcp_erp_handle_failed(int want, struct zfcp_adapter *adapter,
+ struct zfcp_port *port,
+ struct scsi_device *sdev)
+{
+   int need = want;
+   struct zfcp_scsi_dev *zsdev;
+
+   switch (want) {
+   case ZFCP_ERP_ACTION_REOPEN_LUN:
+   zsdev = sdev_to_zfcp(sdev);
+   if (atomic_read(>status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+   need = 0;
+   break;
+   case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
+   if (atomic_read(>status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+   need = 0;
+   break;
+   case ZFCP_ERP_ACTION_REOPEN_PORT:
+   if (atomic_read(>status) &
+   ZFCP_STATUS_COMMON_ERP_FAILED) {
+   need = 0;
+   /* ensure propagation of failed status to new devices */
+   zfcp_erp_set_port_status(
+   port, ZFCP_STATUS_COMMON_ERP_FAILED);
+   }
+   break;
+   case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
+   if (atomic_read(>status) &
+   ZFCP_STATUS_COMMON_ERP_FAILED) {
+   need = 0;
+   /* ensure propagation of failed status to new devices */
+   zfcp_erp_set_adapter_status(
+   adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
+   }
+   break;
+   default:
+   need = 0;
+   break;
+   }
+
+   return need;
+}
+
 static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
 struct zfcp_port *port,
 struct scsi_device *sdev)
@@ -266,6 +309,12 @@ static int zfcp_erp_action_enqueue(int want, struct 
zfcp_adapter *adapter,
int retval = 1, need;
struct zfcp_erp_action *act;
 
+   need = zfcp_erp_handle_failed(want, adapter, port, sdev);
+   if (!need) {
+   need = ZFCP_ERP_ACTION_FAILED; /* marker for trace */
+   goto out;
+   }
+
if (!adapter->erp_thread)
return -EIO;
 
@@ -314,12 +363,6 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter 
*adapter,
zfcp_erp_adapter_block(adapter, clear_mask);
zfcp_scsi_schedule_rports_block(adapter);
 
-   /* ensure propagation of failed status to new devices */
-   if (atomic_read(>status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
-   zfcp_erp_set_adapter_status(adapter,
-   ZFCP_STATUS_COMMON_ERP_FAILED);
-   return -EIO;
-   }
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
   adapter, NULL, NULL, id, 0);
 }
@@ -338,12 +381,8 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, 
int clear, char *id)
zfcp_scsi_schedule_rports_block(adapter);
 

[PATCH 03/25] zfcp: fix misleading REC trigger trace where erp_action setup failed

2018-05-17 Thread Steffen Maier
If a SCSI device is deleted during scsi_eh host reset, we cannot get a
reference to the SCSI device anymore since scsi_device_get returns !=0
by design. Assuming the recovery of adapter and port(s) was successful,
zfcp_erp_strategy_followup_success() attempts to trigger a LUN reset for
the half-gone SCSI device. Unfortunately, it causes the following confusing
trace record which states that zfcp will do a LUN recovery as "ERP need" is
ZFCP_ERP_ACTION_REOPEN_LUN == 1 and equals "ERP want".

Old example trace record formatted with zfcpdbf from s390-tools:

Tag:   : ersfs_3 ERP, trigger, unit reopen, port reopen succeeded
LUN: 0x
WWPN   : 0x
D_ID   : 0x
Adapter status : 0x5400050b
Port status: 0x5401
LUN status : 0x4000 ZFCP_STATUS_COMMON_RUNNING
but not ZFCP_STATUS_COMMON_UNBLOCKED as it
was closed on close part of adapter reopen
ERP want   : 0x01
ERP need   : 0x01   misleading

However, zfcp_erp_setup_act() returns NULL as it cannot get the reference.
Hence, zfcp_erp_action_enqueue() takes an early goto out and _NO_ recovery
actually happens.

We always do want the recovery trigger trace record even if no erp_action
could be enqueued as in this case. For other cases where we did not enqueue
an erp_action, 'need' has always been zero to indicate this. In order to
indicate above goto out, introduce an eyecatcher "flag" to mark the
"ERP need" as 'not needed' but still keep the information which erp_action
type, that zfcp_erp_required_act() had decided upon, is needed.
0xc_ is chosen to be visibly different from 0x0_ in "ERP want".

New example trace record formatted with zfcpdbf from s390-tools:

Tag:   : ersfs_3 ERP, trigger, unit reopen, port reopen succeeded
LUN: 0x
WWPN   : 0x
D_ID   : 0x
Adapter status : 0x5400050b
Port status: 0x5401
LUN status : 0x4000
ERP want   : 0x01
ERP need   : 0xc1   would need LUN ERP, but no action set up
   ^

Before v2.6.38 commit ae0904f60fab ("[SCSI] zfcp: Redesign of the debug
tracing for recovery actions.") we could detect this case because the
"erp_action" field in the trace was NULL. The rework removed erp_action
as argument and field from the trace.

This patch here is for tracing. A fix to allow LUN recovery in the case at
hand is a topic for a separate patch.

See also commit fdbd1c5e27da ("[SCSI] zfcp: Allow running unit/LUN shutdown
without acquiring reference") for a similar case and background info.

Signed-off-by: Steffen Maier 
Fixes: ae0904f60fab ("[SCSI] zfcp: Redesign of the debug tracing for recovery 
actions.")
Cc:  #2.6.38+
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 1d91a32db08e..d9cd25b56cfa 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -35,11 +35,23 @@ enum zfcp_erp_steps {
ZFCP_ERP_STEP_LUN_OPENING   = 0x2000,
 };
 
+/**
+ * enum zfcp_erp_act_type - Type of ERP action object.
+ * @ZFCP_ERP_ACTION_REOPEN_LUN: LUN recovery.
+ * @ZFCP_ERP_ACTION_REOPEN_PORT: Port recovery.
+ * @ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: Forced port recovery.
+ * @ZFCP_ERP_ACTION_REOPEN_ADAPTER: Adapter recovery.
+ * @ZFCP_ERP_ACTION_NONE: Eyecatcher pseudo flag to bitwise or-combine with
+ *   either of the other enum values.
+ *   Used to indicate that an ERP action could not be
+ *   set up despite a detected need for some recovery.
+ */
 enum zfcp_erp_act_type {
ZFCP_ERP_ACTION_REOPEN_LUN = 1,
ZFCP_ERP_ACTION_REOPEN_PORT= 2,
ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3,
ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4,
+   ZFCP_ERP_ACTION_NONE   = 0xc0,
 };
 
 enum zfcp_erp_act_state {
@@ -257,8 +269,10 @@ static int zfcp_erp_action_enqueue(int want, struct 
zfcp_adapter *adapter,
goto out;
 
act = zfcp_erp_setup_act(need, act_status, adapter, port, sdev);
-   if (!act)
+   if (!act) {
+   need |= ZFCP_ERP_ACTION_NONE; /* marker for trace */
goto out;
+   }
atomic_or(ZFCP_STATUS_ADAPTER_ERP_PENDING, >status);
++adapter->erp_total_count;
list_add_tail(>list, >erp_ready_head);
-- 
2.16.3



[PATCH 07/25] zfcp: fix missing REC trigger trace on enqueue without ERP thread

2018-05-17 Thread Steffen Maier
Example trace record formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : REC
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1  ZFCP_DBF_REC_TRIG
Tag: ...
LUN: 0x...
WWPN   : 0x...
D_ID   : 0x...
Adapter status : 0x...
Port status: 0x...
LUN status : 0x...
Ready count: 0x...
Running count  : 0x...
ERP want   : 0x0.   ZFCP_ERP_ACTION_REOPEN_...
ERP need   : 0xc0   ZFCP_ERP_ACTION_NONE

Signed-off-by: Steffen Maier 
Cc:  #2.6.38+
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 20fe59300d0e..69dfb328dba4 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -315,8 +315,11 @@ static int zfcp_erp_action_enqueue(int want, struct 
zfcp_adapter *adapter,
goto out;
}
 
-   if (!adapter->erp_thread)
-   return -EIO;
+   if (!adapter->erp_thread) {
+   need = ZFCP_ERP_ACTION_NONE; /* marker for trace */
+   retval = -EIO;
+   goto out;
+   }
 
need = zfcp_erp_required_act(want, adapter, port, sdev);
if (!need)
-- 
2.16.3



[PATCH 15/25] workqueue,zfcp: set description for port work items with their WWPN as context

2018-05-17 Thread Steffen Maier
As a prerequisite, complement commit 3d1cb2059d93 ("workqueue: include
workqueue info when printing debug dump of a worker task") to be usable
with kernel modules by exporting the symbol set_worker_desc().
Current built-in user was introduced with commit ef3b101925f2 ("writeback:
set worker desc to identify writeback workers in task dumps").

Can help distinguishing work items which do not have adapter scope.
Description is printed out with task dump for debugging on
WARN, BUG, panic, or magic-sysrq [show-task-states(t)].

Example:
$ echo 0 >| /sys/bus/ccw/drivers/zfcp/0.0.1880/0x50050763031bd327/failed &
$ echo 't' >| /proc/sysrq-trigger
$ dmesg
sysrq: SysRq : Show State
  taskPC stack   pid father
...
zfcp_q_0.0.1880 S14640  2165  2 0x0200
Call Trace:
([<009df464>] __schedule+0xbf4/0xc78)
 [<009df57c>] schedule+0x94/0xc0
 [<00168654>] rescuer_thread+0x33c/0x3a0
 [<0016f8be>] kthread+0x166/0x178
 [<009e71f2>] kernel_thread_starter+0x6/0xc
 [<009e71ec>] kernel_thread_starter+0x0/0xc
no locks held by zfcp_q_0.0.1880/2165.
...
kworker/u512:2  D11280  2193  2 0x0200
Workqueue: zfcp_q_0.0.1880 zfcp_scsi_rport_work [zfcp] (zrpd-50050763031bd327)
^
Call Trace:
([<009df464>] __schedule+0xbf4/0xc78)
 [<009df57c>] schedule+0x94/0xc0
 [<009e50c0>] schedule_timeout+0x488/0x4d0
 [<001e425c>] msleep+0x5c/0x78  >>test code only<<
 [<03ff8008a21e>] zfcp_scsi_rport_work+0xbe/0x100 [zfcp]
 [<00167154>] process_one_work+0x3b4/0x718
 [<0016771c>] worker_thread+0x264/0x408
 [<0016f8be>] kthread+0x166/0x178
 [<009e71f2>] kernel_thread_starter+0x6/0xc
 [<009e71ec>] kernel_thread_starter+0x0/0xc
2 locks held by kworker/u512:2/2193:
 #0:  (name){.+}, at: [<00166f4e>] process_one_work+0x1ae/0x718
 #1:  ((&(>rport_work)->work)){+.+.+.}, at: [<00166f4e>] 
process_one_work+0x1ae/0x718
...
=
Showing busy workqueues and worker pools:
workqueue zfcp_q_0.0.1880: flags=0x2000a
  pwq 512: cpus=0-255 flags=0x4 nice=0 active=1/1
in-flight: 2193:zfcp_scsi_rport_work [zfcp]
pool 512: cpus=0-255 flags=0x4 nice=0 hung=0s workers=4 idle: 5 2354 2311

Work items with adapter scope are already identified by the workqueue name
"zfcp_q_" and the work item function name.

Signed-off-by: Steffen Maier 
Cc: Tejun Heo 
Cc: Lai Jiangshan 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_fc.c   | 2 ++
 drivers/s390/scsi/zfcp_scsi.c | 3 +++
 kernel/workqueue.c| 1 +
 3 files changed, 6 insertions(+)

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 6162cf57a20a..2ad80c43f674 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -425,6 +425,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
struct zfcp_port *port = container_of(work, struct zfcp_port,
  gid_pn_work);
 
+   set_worker_desc("zgidpn%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */
ret = zfcp_fc_ns_gid_pn(port);
if (ret) {
/* could not issue gid_pn for some reason */
@@ -559,6 +560,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
container_of(work, struct zfcp_port, test_link_work);
int retval;
 
+   set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */
get_device(>dev);
port->rport_task = RPORT_DEL;
zfcp_scsi_rport_work(>rport_work);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index fcc832b73960..0f7830ffd40a 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -730,6 +730,9 @@ void zfcp_scsi_rport_work(struct work_struct *work)
struct zfcp_port *port = container_of(work, struct zfcp_port,
  rport_work);
 
+   set_worker_desc("zrp%c-%16llx",
+   (port->rport_task == RPORT_ADD) ? 'a' : 'd',
+   port->wwpn); /* < WORKER_DESC_LEN=24 */
while (port->rport_task) {
if (port->rport_task == RPORT_ADD) {
port->rport_task = RPORT_NONE;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index ca7959be8aaa..4e6fa755ebdc 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4350,6 +4350,7 @@ void set_worker_desc(const char *fmt, ...)
worker->desc_valid = true;
}
 }
+EXPORT_SYMBOL_GPL(set_worker_desc);
 
 /**
  * print_worker_info - print out worker information and description
-- 
2.16.3



[PATCH 13/25] zfcp: decouple TMFs from scsi_cmnd by using fc_block_rport

2018-05-17 Thread Steffen Maier
Intentionally retrieve the rport by walking SCSI common code objects
rather than zfcp_sdev->port->rport.

The latter is used for pairing the calls to fc_remote_port_add() and
fc_remote_port_delete(). [see v2.6.31 commit 379d6bf6573e ("[SCSI] zfcp:
Add port only once to FC transport class")]

zfcp_scsi_rport_register() sets zfcp_port.rport to what
fc_remote_port_add() returned.
zfcp_scsi_rport_block() sets zfcp_port.rport = NULL after having called
fc_remote_port_delete().

Hence, while an rport is blocked (or in any subsequent state due to
scsi_transport_fc timeouts such as fast_io_fail_tmo or dev_loss_tmo),
zfcp_port.rport is NULL and cannot serve as argument to fc_block_rport().

During zfcp recovery, a just recovered zfcp_port can have the UNBLOCKED
status flag, but an async rport unblocking has only started via
zfcp_scsi_schedule_rport_register() in zfcp_erp_try_rport_unblock()
[see v4.10 commit 6f2ce1c6af37 ("scsi: zfcp: fix rport unblock race with
LUN recovery")] in zfcp_erp_action_cleanup(). Now zfcp_erp_wait() can
return. This would be sufficient to successfully send a TMF.
But the rport can still be blocked and zfcp_port.rport can still be NULL
until zfcp_port.rport_work was scheduled and has actually called
fc_remote_port_add() and assigned its return value to zfcp_port.rport.
We need an unblocked rport for a successful scsi_eh TUR.

Similarly, for a zfcp_port which has just lost its UNBLOCKED status flag,
the return of zfcp_erp_wait() can race with zfcp_port.rport_work queued
by zfcp_scsi_schedule_rport_block(). Therefore we cannot reliably access
zfcp_port.rport. However, we'd like to get fc_rport_block()'s opinion on
when fast_io_fail_tmo triggered. While we might use
flush_work(>rport_work) to sync with the work item, we can simply use
the other way to get an rport pointer.

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---

Notes:
Changes since RFC:

For consistency renamed from "zfcp: use fc_block_rport for TMFs and
host reset to decouple from scsi_cmnd".

zfcp_scsi_eh_host_reset_handler() will be converted in a later patch.
Therefore, this patch here does not touch the host reset case any more.

Since the previous "[RFC 6/9] scsi: fc: start decoupling fc_block_scsi_eh
from scsi_cmnd" was queued for 4.14 already, I dropped it from this new
patch set version and simply depend on it.

Intentionally retrieve the rport by walking SCSI common code objects
rather than zfcp_sdev->port->rport.

This also fixes the problem that we could not synchronize if port->rport
is NULL but still continued as if the TMF was successful as Hannes
correctly pointed out.

 drivers/s390/scsi/zfcp_scsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index e77e43a0630a..e0c5735cf3db 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -270,6 +270,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, 
u8 tm_flags)
struct scsi_device *sdev = scpnt->device;
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
+   struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
struct zfcp_fsf_req *fsf_req = NULL;
int retval = SUCCESS, ret;
int retry = 3;
@@ -281,7 +282,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, 
u8 tm_flags)
 
zfcp_dbf_scsi_devreset("wait", sdev, tm_flags, NULL);
zfcp_erp_wait(adapter);
-   ret = fc_block_scsi_eh(scpnt);
+   ret = fc_block_rport(rport);
if (ret) {
zfcp_dbf_scsi_devreset("fiof", sdev, tm_flags, NULL);
return ret;
-- 
2.16.3



[PATCH 12/25] zfcp: decouple SCSI setup of TMF from scsi_cmnd

2018-05-17 Thread Steffen Maier
Actually change the signature of zfcp_fsf_fcp_task_mgmt().
Since it was prepared in the previous patch, we only need to delete
a local auto variable which is now the intended argument.

Prepare zfcp_fsf_fcp_task_mgmt's caller zfcp_task_mgmt_function()
to have its function body only depend on a scsi_device and derived objects.

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---

Notes:
Changes since RFC:

Since the FCP channel always requires a valid LUN handle,
we now use scsi_device as context data with any TMF instead of
zfcp_port for FCP_TMF_TGT_RESET and an optional scsi_device for
FCP_TMF_LUN_RESET.

Thus, zfcp_scsi_forget_cmnds() does not need a change anymore and
zfcp_task_mgmt_function() needs less changes because the tracing
with a mandatory scsi_device is simpler.

 drivers/s390/scsi/zfcp_ext.h  |  3 ++-
 drivers/s390/scsi/zfcp_fsf.c  | 12 ++--
 drivers/s390/scsi/zfcp_scsi.c |  2 +-
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 78bcd80d0509..e317c4b513c9 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -123,7 +123,8 @@ 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 struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *, u8);
+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 *);
 extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int);
 
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 5bc84eaa6948..d86c3bf71664 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2314,17 +2314,17 @@ static void zfcp_fsf_fcp_task_mgmt_handler(struct 
zfcp_fsf_req *req)
 }
 
 /**
- * zfcp_fsf_fcp_task_mgmt - send SCSI task management command
- * @scmnd: SCSI command to send the task management command for
- * @tm_flags: unsigned byte for task management flags
- * Returns: on success pointer to struct fsf_req, NULL otherwise
+ * zfcp_fsf_fcp_task_mgmt() - Send SCSI task management command (TMF).
+ * @sdev: Pointer to SCSI device to send the task management command to.
+ * @tm_flags: Unsigned byte for task management flags.
+ *
+ * Return: On success pointer to struct zfcp_fsf_req, %NULL otherwise.
  */
-struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
+struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev,
u8 tm_flags)
 {
struct zfcp_fsf_req *req = NULL;
struct fcp_cmnd *fcp_cmnd;
-   struct scsi_device *sdev = scmnd->device;
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio;
 
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 0afc546b71df..e77e43a0630a 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -275,7 +275,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, 
u8 tm_flags)
int retry = 3;
 
while (retry--) {
-   fsf_req = zfcp_fsf_fcp_task_mgmt(scpnt, tm_flags);
+   fsf_req = zfcp_fsf_fcp_task_mgmt(sdev, tm_flags);
if (fsf_req)
break;
 
-- 
2.16.3



[PATCH 11/25] zfcp: decouple FSF request setup of TMF from scsi_cmnd

2018-05-17 Thread Steffen Maier
In zfcp_fsf_fcp_task_mgmt() resolve the still old argument scsi_cmnd
into scsi_device very early and only depend on scsi_device and derived
objects in the function body.

This prepares to later change the function signature replacing the
scsi_cmnd argument with scsi_device.

Signed-off-by: Steffen Maier 
Reviewed-by: Benjamin Block 
---

Notes:
Changes since RFC:

Since the FCP channel always requires a valid LUN handle,
we now use scsi_device as context data with any TMF instead of either
scsi_device for FCP_TMF_LUN_RESET or zfcp_port for FCP_TMF_TGT_RESET.

Thus, zfcp_fc_fcp_tm() no longer needs a change.

This also fixes a kernel panic due to the unconditional dereference with
sdev_to_zfcp(sdev) where sdev could have been NULL later in the patch set.

 drivers/s390/scsi/zfcp_fsf.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 8bc768a01ef5..5bc84eaa6948 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2324,7 +2324,8 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct 
scsi_cmnd *scmnd,
 {
struct zfcp_fsf_req *req = NULL;
struct fcp_cmnd *fcp_cmnd;
-   struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device);
+   struct scsi_device *sdev = scmnd->device;
+   struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio;
 
if (unlikely(!(atomic_read(_sdev->status) &
@@ -2344,7 +2345,8 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct 
scsi_cmnd *scmnd,
goto out;
}
 
-   req->data = scmnd->device;
+   req->data = sdev;
+
req->handler = zfcp_fsf_fcp_task_mgmt_handler;
req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
req->qtcb->header.port_handle = zfcp_sdev->port->handle;
@@ -2355,7 +2357,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct 
scsi_cmnd *scmnd,
zfcp_qdio_set_sbale_last(qdio, >qdio_req);
 
fcp_cmnd = >qtcb->bottom.io.fcp_cmnd.iu;
-   zfcp_fc_fcp_tm(fcp_cmnd, scmnd->device, tm_flags);
+   zfcp_fc_fcp_tm(fcp_cmnd, sdev, tm_flags);
 
zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT);
if (!zfcp_fsf_req_send(req))
-- 
2.16.3



[PATCH 10/25] zfcp: split FCP_CMND IU setup between SCSI I/O and TMF again

2018-05-17 Thread Steffen Maier
This reverts commit 2443c8b23aea ("[SCSI] zfcp: Merge FCP task management
setup with regular FCP command setup"), because this introduced a
dependency on the unsuitable SCSI command for scsi_eh / TMF.

Signed-off-by: Steffen Maier 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_fc.h  | 22 ++
 drivers/s390/scsi/zfcp_fsf.c |  4 ++--
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
index 6a397ddaadf0..3cd74729cfb9 100644
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -207,21 +207,14 @@ struct zfcp_fc_wka_ports {
  * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
  * @fcp: fcp_cmnd to setup
  * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
- * @tm: task management flags to setup task management command
  */
 static inline
-void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi,
-u8 tm_flags)
+void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
 {
u32 datalen;
 
int_to_scsilun(scsi->device->lun, (struct scsi_lun *) >fc_lun);
 
-   if (unlikely(tm_flags)) {
-   fcp->fc_tm_flags = tm_flags;
-   return;
-   }
-
fcp->fc_pri_ta = FCP_PTA_SIMPLE;
 
if (scsi->sc_data_direction == DMA_FROM_DEVICE)
@@ -240,6 +233,19 @@ void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct 
scsi_cmnd *scsi,
}
 }
 
+/**
+ * zfcp_fc_fcp_tm() - Setup FCP command as task management command.
+ * @fcp: Pointer to FCP_CMND IU to set up.
+ * @dev: Pointer to SCSI_device where to send the task management command.
+ * @tm_flags: Task management flags to setup tm command.
+ */
+static inline
+void zfcp_fc_fcp_tm(struct fcp_cmnd *fcp, struct scsi_device *dev, u8 tm_flags)
+{
+   int_to_scsilun(dev->lun, (struct scsi_lun *) >fc_lun);
+   fcp->fc_tm_flags = tm_flags;
+}
+
 /**
  * zfcp_fc_evap_fcp_rsp - evaluate FCP RSP IU and update scsi_cmnd accordingly
  * @fcp_rsp: FCP RSP IU to evaluate
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index a95070c7cad8..8bc768a01ef5 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2260,7 +2260,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
 
BUILD_BUG_ON(sizeof(struct fcp_cmnd) > FSF_FCP_CMND_SIZE);
fcp_cmnd = >qtcb->bottom.io.fcp_cmnd.iu;
-   zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0);
+   zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd);
 
if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) &&
scsi_prot_sg_count(scsi_cmnd)) {
@@ -2355,7 +2355,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct 
scsi_cmnd *scmnd,
zfcp_qdio_set_sbale_last(qdio, >qdio_req);
 
fcp_cmnd = >qtcb->bottom.io.fcp_cmnd.iu;
-   zfcp_fc_scsi_to_fcp(fcp_cmnd, scmnd, tm_flags);
+   zfcp_fc_fcp_tm(fcp_cmnd, scmnd->device, tm_flags);
 
zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT);
if (!zfcp_fsf_req_send(req))
-- 
2.16.3



[PATCH 02/25] zfcp: fix missing SCSI trace for retry of abort / scsi_eh TMF

2018-05-17 Thread Steffen Maier
We already have a SCSI trace for the end of abort and scsi_eh TMF. Due to
zfcp_erp_wait() and fc_block_scsi_eh() time can pass between the
start of our eh callback and an actual send/recv of an abort / TMF request.
In order to see the temporal sequence including any abort / TMF send
retries, add a trace before the above two blocking functions.
This supports problem determination with scsi_eh and parallel zfcp ERP.

No need to explicitly trace the beginning of our eh callback, since we
typically can send an abort / TMF and see its HBA response (in the worst
case, it's a pseudo response on dismiss all of adapter recovery, e.g. due
to an FSF request timeout [fsrth_1] of the abort / TMF). If we cannot send,
we now get a trace record for the first "abrt_wt" or "[lt]r_wait" which
denotes almost the beginning of the callback.

No need to explicitly trace the wakeup after the above two blocking
functions because the next retry loop causes another trace in any case
and that is sufficient.

Example trace records formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : SCSI
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1
Tag: abrt_wtabort, before zfcp_erp_wait()
Request ID : 0x none (invalid)
SCSI ID: 0x
SCSI LUN   : 0x
SCSI LUN high  : 0x
SCSI result: 0x
SCSI retries   : 0x
SCSI allowed   : 0x
SCSI scribble  : 0x
SCSI opcode: 
FCP rsp inf cod: 0x..   none (invalid)
FCP rsp IU : ...none (invalid)

Timestamp  : ...
Area   : SCSI
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1
Tag: lr_waitLUN reset, before zfcp_erp_wait()
Request ID : 0x none (invalid)
SCSI ID: 0x
SCSI LUN   : 0x
SCSI LUN high  : 0x
SCSI result: 0x...  unrelated
SCSI retries   : 0x..   unrelated
SCSI allowed   : 0x..   unrelated
SCSI scribble  : 0x...  unrelated
SCSI opcode: ...unrelated
FCP rsp inf cod: 0x..   none (invalid)
FCP rsp IU : ...none (invalid)

Signed-off-by: Steffen Maier 
Fixes: 63caf367e1c9 ("[SCSI] zfcp: Improve reliability of SCSI eh handlers in 
zfcp")
Fixes: af4de36d911a ("[SCSI] zfcp: Block scsi_eh thread for rport state 
BLOCKED")
Cc:  #2.6.38+
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_scsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index a62357f5e8b4..4fdb1665b0e6 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -181,6 +181,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd 
*scpnt)
if (abrt_req)
break;
 
+   zfcp_dbf_scsi_abort("abrt_wt", scpnt, NULL);
zfcp_erp_wait(adapter);
ret = fc_block_scsi_eh(scpnt);
if (ret) {
@@ -277,6 +278,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, 
u8 tm_flags)
if (fsf_req)
break;
 
+   zfcp_dbf_scsi_devreset("wait", scpnt, tm_flags, NULL);
zfcp_erp_wait(adapter);
ret = fc_block_scsi_eh(scpnt);
if (ret) {
-- 
2.16.3



[PATCH 04/25] zfcp: fix missing REC trigger trace on terminate_rport_io early return

2018-05-17 Thread Steffen Maier
get_device() and its internally used kobject_get() only return NULL
if they get passed NULL as argument. zfcp_get_port_by_wwpn() loops over
adapter->port_list so the iteration variable port is always non-NULL.
Struct device is embedded in struct zfcp_port so >dev is always
non-NULL. This is the argument to get_device().
However, if we get an fc_rport in terminate_rport_io() for which we cannot
find a match within zfcp_get_port_by_wwpn(), the latter can return NULL.
v2.6.30 commit 70932935b61e ("[SCSI] zfcp: Fix oops when port disappears")
introduced an early return without adding a trace record for this case.
Even if we don't need recovery in this case, for debugging we should still
see that our callback was invoked originally by scsi_transport_fc.

Example trace record formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : REC
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1
Tag: sctrpinSCSI terminate rport I/O, no zfcp port
LUN: 0x none (invalid)
WWPN   : 0x   WWPN
D_ID   : 0x  N_Port-ID
Adapter status : 0x...
Port status: 0x unknown (-1)
LUN status : 0x none (invalid)
Ready count: 0x...
Running count  : 0x...
ERP want   : 0x03   ZFCP_ERP_ACTION_REOPEN_PORT_FORCED
ERP need   : 0xc0   ZFCP_ERP_ACTION_NONE

Signed-off-by: Steffen Maier 
Fixes: 70932935b61e ("[SCSI] zfcp: Fix oops when port disappears")
Cc:  #2.6.38+
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_erp.c  | 20 
 drivers/s390/scsi/zfcp_ext.h  |  3 +++
 drivers/s390/scsi/zfcp_scsi.c |  5 +
 3 files changed, 28 insertions(+)

diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index d9cd25b56cfa..3489b1bc9121 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -283,6 +283,26 @@ static int zfcp_erp_action_enqueue(int want, struct 
zfcp_adapter *adapter,
return retval;
 }
 
+void zfcp_erp_port_forced_no_port_dbf(char *id, struct zfcp_adapter *adapter,
+ u64 port_name, u32 port_id)
+{
+   unsigned long flags;
+   static /* don't waste stack */ struct zfcp_port tmpport;
+
+   write_lock_irqsave(>erp_lock, flags);
+   /* Stand-in zfcp port with fields just good enough for
+* zfcp_dbf_rec_trig() and zfcp_dbf_set_common().
+* Under lock because tmpport is static.
+*/
+   atomic_set(, -1); /* unknown */
+   tmpport.wwpn = port_name;
+   tmpport.d_id = port_id;
+   zfcp_dbf_rec_trig(id, adapter, , NULL,
+ ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
+ ZFCP_ERP_ACTION_NONE);
+   write_unlock_irqrestore(>erp_lock, flags);
+}
+
 static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
int clear_mask, char *id)
 {
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index e55f42ce1168..3299bd345076 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -55,6 +55,9 @@ extern void zfcp_dbf_scsi_eh(char *tag, struct zfcp_adapter 
*adapter,
 /* zfcp_erp.c */
 extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
 extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32);
+extern void zfcp_erp_port_forced_no_port_dbf(char *id,
+struct zfcp_adapter *adapter,
+u64 port_name, u32 port_id);
 extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *);
 extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *);
 extern void zfcp_erp_set_port_status(struct zfcp_port *, u32);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 4fdb1665b0e6..478e7ef9ea2f 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -605,6 +605,11 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport 
*rport)
if (port) {
zfcp_erp_port_forced_reopen(port, 0, "sctrpi1");
put_device(>dev);
+   } else {
+   zfcp_erp_port_forced_no_port_dbf(
+   "sctrpin", adapter,
+   rport->port_name /* zfcp_scsi_rport_register */,
+   rport->port_id /* zfcp_scsi_rport_register */);
}
 }
 
-- 
2.16.3



[PATCH 01/25] zfcp: fix missing SCSI trace for result of eh_host_reset_handler

2018-05-17 Thread Steffen Maier
For problem determination we need to see whether and why we were
successful or not. This allows deduction of scsi_eh escalation.

Example trace record formatted with zfcpdbf from s390-tools:

Timestamp  : ...
Area   : SCSI
Subarea: 00
Level  : 1
Exception  : -
CPU ID : ..
Caller : 0x...
Record ID  : 1
Tag: schrh_rSCSI host reset handler result
Request ID : 0x none (invalid)
SCSI ID: 0x none (invalid)
SCSI LUN   : 0x none (invalid)
SCSI LUN high  : 0x none (invalid)
SCSI result: 0x2002 field re-used for midlayer value: SUCCESS
or in other cases: 0x2009 == FAST_IO_FAIL
SCSI retries   : 0xff   none (invalid)
SCSI allowed   : 0xff   none (invalid)
SCSI scribble  : 0x none (invalid)
SCSI opcode:    none (invalid)
FCP rsp inf cod: 0xff   none (invalid)
FCP rsp IU :    none (invalid)
  

v2.6.35 commit a1dbfddd02d2 ("[SCSI] zfcp: Pass return code from
fc_block_scsi_eh to scsi eh") introduced the first return with something
other than the previously hardcoded single SUCCESS return path.

Signed-off-by: Steffen Maier 
Fixes: a1dbfddd02d2 ("[SCSI] zfcp: Pass return code from fc_block_scsi_eh to 
scsi eh")
Cc:  #2.6.38+
Reviewed-by: Jens Remus 
Reviewed-by: Benjamin Block 
---
 drivers/s390/scsi/zfcp_dbf.c  | 40 
 drivers/s390/scsi/zfcp_ext.h  |  2 ++
 drivers/s390/scsi/zfcp_scsi.c | 11 ++-
 3 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index a8b831000b2d..1e5ea5e4992b 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -643,6 +643,46 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd 
*sc,
spin_unlock_irqrestore(>scsi_lock, flags);
 }
 
+/**
+ * zfcp_dbf_scsi_eh() - Trace event for special cases of scsi_eh callbacks.
+ * @tag: Identifier for event.
+ * @adapter: Pointer to zfcp adapter as context for this event.
+ * @scsi_id: SCSI ID/target to indicate scope of task management function 
(TMF).
+ * @ret: Return value of calling function.
+ *
+ * This SCSI trace variant does not depend on any of:
+ * scsi_cmnd, zfcp_fsf_req, scsi_device.
+ */
+void zfcp_dbf_scsi_eh(char *tag, struct zfcp_adapter *adapter,
+ unsigned int scsi_id, int ret)
+{
+   struct zfcp_dbf *dbf = adapter->dbf;
+   struct zfcp_dbf_scsi *rec = >scsi_buf;
+   unsigned long flags;
+   static int const level = 1;
+
+   if (unlikely(!debug_level_enabled(adapter->dbf->scsi, level)))
+   return;
+
+   spin_lock_irqsave(>scsi_lock, flags);
+   memset(rec, 0, sizeof(*rec));
+
+   memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+   rec->id = ZFCP_DBF_SCSI_CMND;
+   rec->scsi_result = ret; /* re-use field, int is 4 bytes and fits */
+   rec->scsi_retries = ~0;
+   rec->scsi_allowed = ~0;
+   rec->fcp_rsp_info = ~0;
+   rec->scsi_id = scsi_id;
+   rec->scsi_lun = (u32)ZFCP_DBF_INVALID_LUN;
+   rec->scsi_lun_64_hi = (u32)(ZFCP_DBF_INVALID_LUN >> 32);
+   rec->host_scribble = ~0;
+   memset(rec->scsi_opcode, 0xff, ZFCP_DBF_SCSI_OPCODE);
+
+   debug_event(dbf->scsi, level, rec, sizeof(*rec));
+   spin_unlock_irqrestore(>scsi_lock, flags);
+}
+
 static debug_info_t *zfcp_dbf_reg(const char *name, int size, int rec_size)
 {
struct debug_info *d;
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index bf8ea4df2bb8..e55f42ce1168 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -49,6 +49,8 @@ extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
 extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
 extern void zfcp_dbf_scsi(char *, int, struct scsi_cmnd *,
  struct zfcp_fsf_req *);
+extern void zfcp_dbf_scsi_eh(char *tag, struct zfcp_adapter *adapter,
+unsigned int scsi_id, int ret);
 
 /* zfcp_erp.c */
 extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 4d2ba5682493..a62357f5e8b4 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -323,15 +323,16 @@ static int zfcp_scsi_eh_host_reset_handler(struct 
scsi_cmnd *scpnt)
 {
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
struct zfcp_adapter *adapter = 

[PATCH 00/25] zfcp: updates for v4.18

2018-05-17 Thread Steffen Maier
James, Martin,

this is the zfcp patch set for the v4.18 merge window.
The patches apply to Martin's 4.18/scsi-queue.
The patches eventually go on top of the bug fix commit
fa89adba1941e4f3b213399b81732a5c12fd9131
("scsi: zfcp: fix infinite iteration on ERP ready list")
in Martin's 4.17/scsi-fixes or James' scsi-fixes
[https://www.spinics.net/lists/linux-scsi/msg120124.html].
There should be no merge conflicts between the fix and this patch set.

Patches 1-7 are debugging/tracing fixes found during function test of 8-14.

Patches 8-14 are the result of an earlier RFC to prepare for changing
scsi_eh callback function arguments to decouple from scsi_cmnd.
[http://www.spinics.net/lists/linux-scsi/msg92.html /
https://marc.info/?l=linux-scsi=150099208822680=2]
The only difference is that I have to defer the conversion of host_reset().

Patches 15-25 are small cleanups / updates.

Jens Remus (3):
  zfcp: assert that the ERP lock is held when tracing a recovery trigger
  zfcp: add port speed capabilities
  zfcp: enhance comments on fc_link_speed and supported_speed

Steffen Maier (22):
  zfcp: fix missing SCSI trace for result of eh_host_reset_handler
  zfcp: fix missing SCSI trace for retry of abort / scsi_eh TMF
  zfcp: fix misleading REC trigger trace where erp_action setup failed
  zfcp: fix missing REC trigger trace on terminate_rport_io early return
  zfcp: fix missing REC trigger trace on terminate_rport_io for
ERP_FAILED
  zfcp: fix missing REC trigger trace for all objects in ERP_FAILED
  zfcp: fix missing REC trigger trace on enqueue without ERP thread
  zfcp: decouple SCSI traces for scsi_eh / TMF from scsi_cmnd
  zfcp: decouple TMF response handler from scsi_cmnd
  zfcp: split FCP_CMND IU setup between SCSI I/O and TMF again
  zfcp: decouple FSF request setup of TMF from scsi_cmnd
  zfcp: decouple SCSI setup of TMF from scsi_cmnd
  zfcp: decouple TMFs from scsi_cmnd by using fc_block_rport
  zfcp: decouple our scsi_eh callbacks from scsi_cmnd
  workqueue,zfcp: set description for port work items with their WWPN as
context
  zfcp: consistently use function name space prefix
  zfcp: remove unused ERP enum values
  zfcp: zfcp_erp_action_exists() does only check for running
  zfcp: remove unused return values of ERP trigger functions
  zfcp: explicitly support initiator in scsi_host_template
  zfcp: support SCSI_ADAPTER_RESET via scsi_host sysfs attribute
host_reset
  zfcp: cleanup indentation for posting FC events

 drivers/s390/scsi/zfcp_dbf.c   |  90 +++
 drivers/s390/scsi/zfcp_dbf.h   |  21 +++--
 drivers/s390/scsi/zfcp_erp.c   | 194 -
 drivers/s390/scsi/zfcp_ext.h   |  16 +++-
 drivers/s390/scsi/zfcp_fc.c|  11 +--
 drivers/s390/scsi/zfcp_fc.h|  22 +++--
 drivers/s390/scsi/zfcp_fsf.c   |  61 -
 drivers/s390/scsi/zfcp_fsf.h   |   6 +-
 drivers/s390/scsi/zfcp_scsi.c  | 141 +++---
 drivers/s390/scsi/zfcp_sysfs.c |   5 +-
 kernel/workqueue.c |   1 +
 11 files changed, 401 insertions(+), 167 deletions(-)

-- 
2.16.3



[PATCH] scsi: snic: fix a couple of spelling mistakes: "COMPLETE"

2018-05-17 Thread Colin King
From: Colin Ian King 

Trivial fix to spelling mistakes/typos:
"SNIC_IOREQ_ABTS_COMPELTE" -> "SNIC_IOREQ_ABTS_COMPLETE"
"SNIC_IOREQ_LR_COMPELTE"   -> "SNIC_IOREQ_LR_COMPLETE"
"SNIC_IOREQ_CMD_COMPELTE"  -> "SNIC_IOREQ_CMD_COMPLETE"

Signed-off-by: Colin Ian King 
---
 drivers/scsi/snic/snic_scsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index d8a376b7882d..d9b2e46424aa 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -47,10 +47,10 @@ static const char * const snic_req_state_str[] = {
[SNIC_IOREQ_NOT_INITED] = "SNIC_IOREQ_NOT_INITED",
[SNIC_IOREQ_PENDING]= "SNIC_IOREQ_PENDING",
[SNIC_IOREQ_ABTS_PENDING] = "SNIC_IOREQ_ABTS_PENDING",
-   [SNIC_IOREQ_ABTS_COMPLETE] = "SNIC_IOREQ_ABTS_COMPELTE",
+   [SNIC_IOREQ_ABTS_COMPLETE] = "SNIC_IOREQ_ABTS_COMPLETE",
[SNIC_IOREQ_LR_PENDING] = "SNIC_IOREQ_LR_PENDING",
-   [SNIC_IOREQ_LR_COMPLETE] = "SNIC_IOREQ_LR_COMPELTE",
-   [SNIC_IOREQ_COMPLETE]   = "SNIC_IOREQ_CMD_COMPELTE",
+   [SNIC_IOREQ_LR_COMPLETE] = "SNIC_IOREQ_LR_COMPLETE",
+   [SNIC_IOREQ_COMPLETE]   = "SNIC_IOREQ_CMD_COMPLETE",
 };
 
 /* snic cmd status strings */
-- 
2.17.0



Re: [PATCH 1/1] qla2xxx: Allow SCSI-MQ to be enabled selectively

2018-05-17 Thread Christoph Hellwig
On Wed, May 16, 2018 at 08:54:11PM -0700, Himanshu Madhani wrote:
> when ql2xmqsupport=1, use that value to selectively
> enable SCSI-MQ

NAK.  This is not something that we should grow driver parameters for.

Btw, should we look into enabling blk-mq by default again now that
all the performance fixes went in and srttled down?


Re: [PATCH 11/40] ipv6/flowlabel: simplify pid namespace lookup

2018-05-17 Thread Christoph Hellwig
On Thu, May 17, 2018 at 12:28:01AM -0500, Eric W. Biederman wrote:
> > struct pid_namespace *proc_pid_namespace(struct inode *inode)
> > {
> > // maybe warn on for s_magic not on procfs??
> > return inode->i_sb->s_fs_info;
> > }
> 
> That should work.  Ideally out of line for the proc_fs.h version.
> Basically it should be a cousin of PDE_DATA.

The version in Al's tree is inline and without the warning as
I didn't want to drag in the magic.h include.  Please look at it for
additional comments, I can send incremental fixups if needed.