1. 20 May, 2020 26 commits
  2. 15 May, 2020 6 commits
  3. 13 May, 2020 1 commit
  4. 12 May, 2020 7 commits
    • Dan Carpenter's avatar
      scsi: scsi_debug: Fix an error handling bug in sdeb_zbc_model_str() · 47742bde
      Dan Carpenter authored
      This test is checking the wrong variable.  It should be testing "res".
      The "sdeb_zbc_model" variable is an enum (unsigned in this situation)
      and we never assign negative values to it.
      
      [mkp: fixed commit desc issue reported by Doug]
      
      Link: https://lore.kernel.org/r/20200509100408.GA5555@mwanda
      Fixes: 9267e0eb ("scsi: scsi_debug: Add ZBC module parameter")
      Acked-by: default avatarDouglas Gilbert <dgilbert@interlog.com>
      Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      47742bde
    • Benjamin Block's avatar
      scsi: zfcp: Move allocation of the shost object to after xconf- and xport-data · d0dff2ac
      Benjamin Block authored
      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 737eb78e ("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 92953c6e ("scsi: zfcp: signal incomplete or error for sync exchange config/port data")
      commit 7e418833 ("scsi: zfcp: diagnostics buffer caching and use for exchange port data")
      commit 08821023 ("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.
      
      Link: https://lore.kernel.org/r/030dd6da318bbb529f0b5268ec65cebcd20fc0a3.1588956679.git.bblock@linux.ibm.comReviewed-by: default avatarSteffen Maier <maier@linux.ibm.com>
      Signed-off-by: default avatarBenjamin Block <bblock@linux.ibm.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      d0dff2ac
    • Benjamin Block's avatar
      scsi: zfcp: Fence early sysfs interfaces for accesses of shost objects · 71159b6e
      Benjamin Block authored
      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.
      
      Link: https://lore.kernel.org/r/ef65366d309993ca91b6917727590ca7ca166c8f.1588956679.git.bblock@linux.ibm.comReviewed-by: default avatarSteffen Maier <maier@linux.ibm.com>
      Signed-off-by: default avatarBenjamin Block <bblock@linux.ibm.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      71159b6e
    • Benjamin Block's avatar
      scsi: zfcp: Fence adapter status propagation for common statuses · 971f2abb
      Benjamin Block authored
      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.
      
      Link: https://lore.kernel.org/r/f51fe5f236a1e3d1ce53379c308777561bfe35e1.1588956679.git.bblock@linux.ibm.comReviewed-by: default avatarSteffen Maier <maier@linux.ibm.com>
      Signed-off-by: default avatarBenjamin Block <bblock@linux.ibm.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      971f2abb
    • Benjamin Block's avatar
      scsi: zfcp: Move p-t-p port allocation to after xport data · ac007adc
      Benjamin Block authored
      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.
      
      Link: https://lore.kernel.org/r/73e5d4ac21e2b37bf0c3ca8e530bc5a5c6e74f8f.1588956679.git.bblock@linux.ibm.comReviewed-by: default avatarSteffen Maier <maier@linux.ibm.com>
      Signed-off-by: default avatarBenjamin Block <bblock@linux.ibm.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      ac007adc
    • Benjamin Block's avatar
      scsi: zfcp: Fence fc_host updates during link-down handling · 990486f3
      Benjamin Block authored
      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().
      
      Link: https://lore.kernel.org/r/f841f2cda61dcd7b8549910c44e1831927459edf.1588956679.git.bblock@linux.ibm.comReviewed-by: default avatarSteffen Maier <maier@linux.ibm.com>
      Signed-off-by: default avatarBenjamin Block <bblock@linux.ibm.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      990486f3
    • Benjamin Block's avatar
      scsi: zfcp: Move fc_host updates during xport data handling into fenced function · 52e61fde
      Benjamin Block authored
      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.
      
      Link: https://lore.kernel.org/r/ae454c2dc6da0b02907c489af91d0b211d331825.1588956679.git.bblock@linux.ibm.comReviewed-by: default avatarSteffen Maier <maier@linux.ibm.com>
      Signed-off-by: default avatarBenjamin Block <bblock@linux.ibm.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      52e61fde