1. 30 May, 2019 5 commits
    • YueHaibing's avatar
      scsi: scsi_dh_alua: Fix possible null-ptr-deref · 12e750bc
      YueHaibing authored
      If alloc_workqueue fails in alua_init, it should return -ENOMEM, otherwise
      it will trigger null-ptr-deref while unloading module which calls
      destroy_workqueue dereference
      wq->lock like this:
      
      BUG: KASAN: null-ptr-deref in __lock_acquire+0x6b4/0x1ee0
      Read of size 8 at addr 0000000000000080 by task syz-executor.0/7045
      
      CPU: 0 PID: 7045 Comm: syz-executor.0 Tainted: G         C        5.1.0+ #28
      Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1
      Call Trace:
       dump_stack+0xa9/0x10e
       __kasan_report+0x171/0x18d
       ? __lock_acquire+0x6b4/0x1ee0
       kasan_report+0xe/0x20
       __lock_acquire+0x6b4/0x1ee0
       lock_acquire+0xb4/0x1b0
       __mutex_lock+0xd8/0xb90
       drain_workqueue+0x25/0x290
       destroy_workqueue+0x1f/0x3f0
       __x64_sys_delete_module+0x244/0x330
       do_syscall_64+0x72/0x2a0
       entry_SYSCALL_64_after_hwframe+0x49/0xbe
      Reported-by: default avatarHulk Robot <hulkci@huawei.com>
      Fixes: 03197b61 ("scsi_dh_alua: Use workqueue for RTPG")
      Signed-off-by: default avatarYueHaibing <yuehaibing@huawei.com>
      Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      12e750bc
    • Lianbo Jiang's avatar
      scsi: smartpqi: properly set both the DMA mask and the coherent DMA mask · 1d94f06e
      Lianbo Jiang authored
      When SME is enabled, the smartpqi driver won't work on the HP DL385 G10
      machine, which causes the failure of kernel boot because it fails to
      allocate pqi error buffer. Please refer to the kernel log:
      ....
      [    9.431749] usbcore: registered new interface driver uas
      [    9.441524] Microsemi PQI Driver (v1.1.4-130)
      [    9.442956] i40e 0000:04:00.0: fw 6.70.48768 api 1.7 nvm 10.2.5
      [    9.447237] smartpqi 0000:23:00.0: Microsemi Smart Family Controller found
               Starting dracut initqueue hook...
      [  OK  ] Started Show Plymouth Boot Scre[    9.471654] Broadcom NetXtreme-C/E driver bnxt_en v1.9.1
      en.
      [  OK  ] Started Forward Password Requests to Plymouth Directory Watch.
      [[0;[    9.487108] smartpqi 0000:23:00.0: failed to allocate PQI error buffer
      ....
      [  139.050544] dracut-initqueue[949]: Warning: dracut-initqueue timeout - starting timeout scripts
      [  139.589779] dracut-initqueue[949]: Warning: dracut-initqueue timeout - starting timeout scripts
      
      Basically, the fact that the coherent DMA mask value wasn't set caused the
      driver to fall back to SWIOTLB when SME is active.
      
      For correct operation, lets call the dma_set_mask_and_coherent() to
      properly set the mask for both streaming and coherent, in order to inform
      the kernel about the devices DMA addressing capabilities.
      Signed-off-by: default avatarLianbo Jiang <lijiang@redhat.com>
      Acked-by: default avatarDon Brace <don.brace@microsemi.com>
      Tested-by: default avatarDon Brace <don.brace@microsemi.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      1d94f06e
    • Steffen Maier's avatar
      scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs) · ef4021fe
      Steffen Maier authored
      When the user tries to remove a zfcp port via sysfs, we only rejected it if
      there are zfcp unit children under the port. With purely automatically
      scanned LUNs there are no zfcp units but only SCSI devices. In such cases,
      the port_remove erroneously continued. We close the port and this
      implicitly closes all LUNs under the port. The SCSI devices survive with
      their private zfcp_scsi_dev still holding a reference to the "removed"
      zfcp_port (still allocated but invisible in sysfs) [zfcp_get_port_by_wwpn
      in zfcp_scsi_slave_alloc]. This is not a problem as long as the fc_rport
      stays blocked. Once (auto) port scan brings back the removed port, we
      unblock its fc_rport again by design.  However, there is no mechanism that
      would recover (open) the LUNs under the port (no "ersfs_3" without
      zfcp_unit [zfcp_erp_strategy_followup_success]).  Any pending or new I/O to
      such LUN leads to repeated:
      
        Done: NEEDS_RETRY Result: hostbyte=DID_IMM_RETRY driverbyte=DRIVER_OK
      
      See also v4.10 commit 6f2ce1c6 ("scsi: zfcp: fix rport unblock race
      with LUN recovery"). Even a manual LUN recovery
      (echo 0 > /sys/bus/scsi/devices/H:C:T:L/zfcp_failed)
      does not help, as the LUN links to the old "removed" port which remains
      to lack ZFCP_STATUS_COMMON_RUNNING [zfcp_erp_required_act].
      The only workaround is to first ensure that the fc_rport is blocked
      (e.g. port_remove again in case it was re-discovered by (auto) port scan),
      then delete the SCSI devices, and finally re-discover by (auto) port scan.
      The port scan includes an fc_rport unblock, which in turn triggers
      a new scan on the scsi target to freshly get new pure auto scan LUNs.
      
      Fix this by rejecting port_remove also if there are SCSI devices
      (even without any zfcp_unit) under this port. Re-use mechanics from v3.7
      commit d99b601b ("[SCSI] zfcp: restore refcount check on port_remove").
      However, we have to give up zfcp_sysfs_port_units_mutex earlier in unit_add
      to prevent a deadlock with scsi_host scan taking shost->scan_mutex first
      and then zfcp_sysfs_port_units_mutex now in our zfcp_scsi_slave_alloc().
      Signed-off-by: default avatarSteffen Maier <maier@linux.ibm.com>
      Fixes: b62a8d9b ("[SCSI] zfcp: Use SCSI device data zfcp scsi dev instead of zfcp unit")
      Fixes: f8210e34 ("[SCSI] zfcp: Allow midlayer to scan for LUNs when running in NPIV mode")
      Cc: <stable@vger.kernel.org> #2.6.37+
      Reviewed-by: default avatarBenjamin Block <bblock@linux.ibm.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      ef4021fe
    • Steffen Maier's avatar
      scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove · d27e5e07
      Steffen Maier authored
      With this early return due to zfcp_unit child(ren), we don't use the
      zfcp_port reference from the earlier zfcp_get_port_by_wwpn() anymore and
      need to put it.
      Signed-off-by: default avatarSteffen Maier <maier@linux.ibm.com>
      Fixes: d99b601b ("[SCSI] zfcp: restore refcount check on port_remove")
      Cc: <stable@vger.kernel.org> #3.7+
      Reviewed-by: default avatarJens Remus <jremus@linux.ibm.com>
      Reviewed-by: default avatarBenjamin Block <bblock@linux.ibm.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      d27e5e07
    • Varun Prakash's avatar
      scsi: libcxgbi: add a check for NULL pointer in cxgbi_check_route() · cc555759
      Varun Prakash authored
      ip_dev_find() can return NULL so add a check for NULL pointer.
      Signed-off-by: default avatarVarun Prakash <varun@chelsio.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      cc555759
  2. 20 May, 2019 4 commits
  3. 14 May, 2019 7 commits
  4. 29 Apr, 2019 24 commits
    • Bart Van Assche's avatar
      scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in tcm_qla2xxx_close_session() · d4023db7
      Bart Van Assche authored
      This patch avoids that lockdep reports the following warning:
      
      =====================================================
      WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected
      5.1.0-rc1-dbg+ #11 Tainted: G        W
      -----------------------------------------------------
      rmdir/1478 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
      00000000e7ac4607 (&(&k->k_lock)->rlock){+.+.}, at: klist_next+0x43/0x1d0
      
      and this task is already holding:
      00000000cf0baf5e (&(&ha->tgt.sess_lock)->rlock){-...}, at: tcm_qla2xxx_close_session+0x57/0xb0 [tcm_qla2xxx]
      which would create a new lock dependency:
       (&(&ha->tgt.sess_lock)->rlock){-...} -> (&(&k->k_lock)->rlock){+.+.}
      
      but this new dependency connects a HARDIRQ-irq-safe lock:
       (&(&ha->tgt.sess_lock)->rlock){-...}
      
      ... which became HARDIRQ-irq-safe at:
        lock_acquire+0xe3/0x200
        _raw_spin_lock_irqsave+0x3d/0x60
        qla2x00_fcport_event_handler+0x1f3d/0x22b0 [qla2xxx]
        qla2x00_async_login_sp_done+0x1dc/0x1f0 [qla2xxx]
        qla24xx_process_response_queue+0xa37/0x10e0 [qla2xxx]
        qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx]
        __handle_irq_event_percpu+0x79/0x3c0
        handle_irq_event_percpu+0x70/0xf0
        handle_irq_event+0x5a/0x8b
        handle_edge_irq+0x12c/0x310
        handle_irq+0x192/0x20a
        do_IRQ+0x73/0x160
        ret_from_intr+0x0/0x1d
        default_idle+0x23/0x1f0
        arch_cpu_idle+0x15/0x20
        default_idle_call+0x35/0x40
        do_idle+0x2bb/0x2e0
        cpu_startup_entry+0x1d/0x20
        start_secondary+0x24d/0x2d0
        secondary_startup_64+0xa4/0xb0
      
      to a HARDIRQ-irq-unsafe lock:
       (&(&k->k_lock)->rlock){+.+.}
      
      ... which became HARDIRQ-irq-unsafe at:
      ...
        lock_acquire+0xe3/0x200
        _raw_spin_lock+0x32/0x50
        klist_add_tail+0x33/0xb0
        device_add+0x7f4/0xb60
        device_create_groups_vargs+0x11c/0x150
        device_create_with_groups+0x89/0xb0
        vtconsole_class_init+0xb2/0x124
        do_one_initcall+0xc5/0x3ce
        kernel_init_freeable+0x295/0x32e
        kernel_init+0x11/0x11b
        ret_from_fork+0x3a/0x50
      
      other info that might help us debug this:
      
       Possible interrupt unsafe locking scenario:
      
             CPU0                    CPU1
             ----                    ----
        lock(&(&k->k_lock)->rlock);
                                     local_irq_disable();
                                     lock(&(&ha->tgt.sess_lock)->rlock);
                                     lock(&(&k->k_lock)->rlock);
        <Interrupt>
          lock(&(&ha->tgt.sess_lock)->rlock);
      
       *** DEADLOCK ***
      
      4 locks held by rmdir/1478:
       #0: 000000002c7f1ba4 (sb_writers#10){.+.+}, at: mnt_want_write+0x32/0x70
       #1: 00000000c85eb147 (&default_group_class[depth - 1]#2/1){+.+.}, at: do_rmdir+0x217/0x2d0
       #2: 000000002b164d6f (&sb->s_type->i_mutex_key#13){++++}, at: vfs_rmdir+0x7e/0x1d0
       #3: 00000000cf0baf5e (&(&ha->tgt.sess_lock)->rlock){-...}, at: tcm_qla2xxx_close_session+0x57/0xb0 [tcm_qla2xxx]
      
      the dependencies between HARDIRQ-irq-safe lock and the holding lock:
      -> (&(&ha->tgt.sess_lock)->rlock){-...} ops: 127 {
         IN-HARDIRQ-W at:
                          lock_acquire+0xe3/0x200
                          _raw_spin_lock_irqsave+0x3d/0x60
                          qla2x00_fcport_event_handler+0x1f3d/0x22b0 [qla2xxx]
                          qla2x00_async_login_sp_done+0x1dc/0x1f0 [qla2xxx]
                          qla24xx_process_response_queue+0xa37/0x10e0 [qla2xxx]
                          qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx]
                          __handle_irq_event_percpu+0x79/0x3c0
                          handle_irq_event_percpu+0x70/0xf0
                          handle_irq_event+0x5a/0x8b
                          handle_edge_irq+0x12c/0x310
                          handle_irq+0x192/0x20a
                          do_IRQ+0x73/0x160
                          ret_from_intr+0x0/0x1d
                          default_idle+0x23/0x1f0
                          arch_cpu_idle+0x15/0x20
                          default_idle_call+0x35/0x40
                          do_idle+0x2bb/0x2e0
                          cpu_startup_entry+0x1d/0x20
                          start_secondary+0x24d/0x2d0
                          secondary_startup_64+0xa4/0xb0
         INITIAL USE at:
                         lock_acquire+0xe3/0x200
                         _raw_spin_lock_irqsave+0x3d/0x60
                         qla2x00_loop_resync+0xb3d/0x2690 [qla2xxx]
                         qla2x00_do_dpc+0xcee/0xf30 [qla2xxx]
                         kthread+0x1d2/0x1f0
                         ret_from_fork+0x3a/0x50
       }
       ... key      at: [<ffffffffa125f700>] __key.62804+0x0/0xfffffffffff7e900 [qla2xxx]
       ... acquired at:
         __lock_acquire+0x11ed/0x1b60
         lock_acquire+0xe3/0x200
         _raw_spin_lock_irqsave+0x3d/0x60
         klist_next+0x43/0x1d0
         device_for_each_child+0x96/0x110
         scsi_target_block+0x3c/0x40 [scsi_mod]
         fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
         qla2x00_mark_device_lost+0x4d3/0x500 [qla2xxx]
         qlt_unreg_sess+0x104/0x2c0 [qla2xxx]
         tcm_qla2xxx_close_session+0xa2/0xb0 [tcm_qla2xxx]
         target_shutdown_sessions+0x17b/0x190 [target_core_mod]
         core_tpg_del_initiator_node_acl+0xf3/0x1f0 [target_core_mod]
         target_fabric_nacl_base_release+0x25/0x30 [target_core_mod]
         config_item_release+0x9f/0x120 [configfs]
         config_item_put+0x29/0x2b [configfs]
         configfs_rmdir+0x3d2/0x520 [configfs]
         vfs_rmdir+0xb3/0x1d0
         do_rmdir+0x25c/0x2d0
         __x64_sys_rmdir+0x24/0x30
         do_syscall_64+0x77/0x220
         entry_SYSCALL_64_after_hwframe+0x49/0xbe
      
      the dependencies between the lock to be acquired
       and HARDIRQ-irq-unsafe lock:
      -> (&(&k->k_lock)->rlock){+.+.} ops: 14568 {
         HARDIRQ-ON-W at:
                          lock_acquire+0xe3/0x200
                          _raw_spin_lock+0x32/0x50
                          klist_add_tail+0x33/0xb0
                          device_add+0x7f4/0xb60
                          device_create_groups_vargs+0x11c/0x150
                          device_create_with_groups+0x89/0xb0
                          vtconsole_class_init+0xb2/0x124
                          do_one_initcall+0xc5/0x3ce
                          kernel_init_freeable+0x295/0x32e
                          kernel_init+0x11/0x11b
                          ret_from_fork+0x3a/0x50
         SOFTIRQ-ON-W at:
                          lock_acquire+0xe3/0x200
                          _raw_spin_lock+0x32/0x50
                          klist_add_tail+0x33/0xb0
                          device_add+0x7f4/0xb60
                          device_create_groups_vargs+0x11c/0x150
                          device_create_with_groups+0x89/0xb0
                          vtconsole_class_init+0xb2/0x124
                          do_one_initcall+0xc5/0x3ce
                          kernel_init_freeable+0x295/0x32e
                          kernel_init+0x11/0x11b
                          ret_from_fork+0x3a/0x50
         INITIAL USE at:
                         lock_acquire+0xe3/0x200
                         _raw_spin_lock+0x32/0x50
                         klist_add_tail+0x33/0xb0
                         device_add+0x7f4/0xb60
                         device_create_groups_vargs+0x11c/0x150
                         device_create_with_groups+0x89/0xb0
                         vtconsole_class_init+0xb2/0x124
                         do_one_initcall+0xc5/0x3ce
                         kernel_init_freeable+0x295/0x32e
                         kernel_init+0x11/0x11b
                         ret_from_fork+0x3a/0x50
       }
       ... key      at: [<ffffffff83f3d900>] __key.15805+0x0/0x40
       ... acquired at:
         __lock_acquire+0x11ed/0x1b60
         lock_acquire+0xe3/0x200
         _raw_spin_lock_irqsave+0x3d/0x60
         klist_next+0x43/0x1d0
         device_for_each_child+0x96/0x110
         scsi_target_block+0x3c/0x40 [scsi_mod]
         fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
         qla2x00_mark_device_lost+0x4d3/0x500 [qla2xxx]
         qlt_unreg_sess+0x104/0x2c0 [qla2xxx]
         tcm_qla2xxx_close_session+0xa2/0xb0 [tcm_qla2xxx]
         target_shutdown_sessions+0x17b/0x190 [target_core_mod]
         core_tpg_del_initiator_node_acl+0xf3/0x1f0 [target_core_mod]
         target_fabric_nacl_base_release+0x25/0x30 [target_core_mod]
         config_item_release+0x9f/0x120 [configfs]
         config_item_put+0x29/0x2b [configfs]
         configfs_rmdir+0x3d2/0x520 [configfs]
         vfs_rmdir+0xb3/0x1d0
         do_rmdir+0x25c/0x2d0
         __x64_sys_rmdir+0x24/0x30
         do_syscall_64+0x77/0x220
         entry_SYSCALL_64_after_hwframe+0x49/0xbe
      
      stack backtrace:
      CPU: 7 PID: 1478 Comm: rmdir Tainted: G        W         5.1.0-rc1-dbg+ #11
      Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
      Call Trace:
       dump_stack+0x86/0xca
       check_usage.cold.59+0x473/0x563
       check_prev_add.constprop.43+0x1f1/0x1170
       __lock_acquire+0x11ed/0x1b60
       lock_acquire+0xe3/0x200
       _raw_spin_lock_irqsave+0x3d/0x60
       klist_next+0x43/0x1d0
       device_for_each_child+0x96/0x110
       scsi_target_block+0x3c/0x40 [scsi_mod]
       fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
       qla2x00_mark_device_lost+0x4d3/0x500 [qla2xxx]
       qlt_unreg_sess+0x104/0x2c0 [qla2xxx]
       tcm_qla2xxx_close_session+0xa2/0xb0 [tcm_qla2xxx]
       target_shutdown_sessions+0x17b/0x190 [target_core_mod]
       core_tpg_del_initiator_node_acl+0xf3/0x1f0 [target_core_mod]
       target_fabric_nacl_base_release+0x25/0x30 [target_core_mod]
       config_item_release+0x9f/0x120 [configfs]
       config_item_put+0x29/0x2b [configfs]
       configfs_rmdir+0x3d2/0x520 [configfs]
       vfs_rmdir+0xb3/0x1d0
       do_rmdir+0x25c/0x2d0
       __x64_sys_rmdir+0x24/0x30
       do_syscall_64+0x77/0x220
       entry_SYSCALL_64_after_hwframe+0x49/0xbe
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      d4023db7
    • Bart Van Assche's avatar
      scsi: qla2xxx: Avoid that qlt_send_resp_ctio() corrupts memory · a861b492
      Bart Van Assche authored
      The "(&ctio->u.status1.sense_data)[i]" where i >= 0 expressions in
      qlt_send_resp_ctio() are probably typos and should have been
      "(&ctio->u.status1.sense_data[4 * i])" instead. Instead of only fixing
      these typos, modify the code for storing sense data such that it becomes
      easy to read. This patch fixes a Coverity complaint about accessing an
      array outside its bounds.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Fixes: be25152c ("qla2xxx: Improve T10-DIF/PI handling in driver.") # v4.11.
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      a861b492
    • Bart Van Assche's avatar
      scsi: qla2xxx: Fix hardirq-unsafe locking · 300ec741
      Bart Van Assche authored
      Since fc_remote_port_delete() must be called with interrupts enabled, do
      not disable interrupts when calling that function. Remove the lockin calls
      from around the put_sess() call. This is safe because the function that is
      called when the final reference is dropped, qlt_unreg_sess(), grabs the
      proper locks. This patch avoids that lockdep reports the following:
      
      WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected
      kworker/2:1/62 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
      0000000009e679b3 (&(&k->k_lock)->rlock){+.+.}, at: klist_next+0x43/0x1d0
      
      and this task is already holding:
      00000000a033b71c (&(&ha->tgt.sess_lock)->rlock){-...}, at: qla24xx_delete_sess_fn+0x55/0xf0 [qla2xxx_scst]
      which would create a new lock dependency:
       (&(&ha->tgt.sess_lock)->rlock){-...} -> (&(&k->k_lock)->rlock){+.+.}
      
      but this new dependency connects a HARDIRQ-irq-safe lock:
       (&(&ha->tgt.sess_lock)->rlock){-...}
      
      ... which became HARDIRQ-irq-safe at:
        lock_acquire+0xe3/0x200
        _raw_spin_lock_irqsave+0x3d/0x60
        qla24xx_report_id_acquisition+0xa69/0xe30 [qla2xxx_scst]
        qla24xx_process_response_queue+0x69e/0x1270 [qla2xxx_scst]
        qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx_scst]
        __handle_irq_event_percpu+0x79/0x3c0
        handle_irq_event_percpu+0x70/0xf0
        handle_irq_event+0x5a/0x8b
        handle_edge_irq+0x12c/0x310
        handle_irq+0x192/0x20a
        do_IRQ+0x73/0x160
        ret_from_intr+0x0/0x1d
        default_idle+0x23/0x1f0
        arch_cpu_idle+0x15/0x20
        default_idle_call+0x35/0x40
        do_idle+0x2bb/0x2e0
        cpu_startup_entry+0x1d/0x20
        start_secondary+0x2a8/0x320
        secondary_startup_64+0xa4/0xb0
      
      to a HARDIRQ-irq-unsafe lock:
       (&(&k->k_lock)->rlock){+.+.}
      
      ... which became HARDIRQ-irq-unsafe at:
      ...
        lock_acquire+0xe3/0x200
        _raw_spin_lock+0x32/0x50
        klist_add_tail+0x33/0xb0
        device_add+0x7e1/0xb50
        device_create_groups_vargs+0x11c/0x150
        device_create_with_groups+0x89/0xb0
        vtconsole_class_init+0xb2/0x124
        do_one_initcall+0xc5/0x3ce
        kernel_init_freeable+0x295/0x32e
        kernel_init+0x11/0x11b
        ret_from_fork+0x3a/0x50
      
      other info that might help us debug this:
      
       Possible interrupt unsafe locking scenario:
      
             CPU0                    CPU1
             ----                    ----
        lock(&(&k->k_lock)->rlock);
                                     local_irq_disable();
                                     lock(&(&ha->tgt.sess_lock)->rlock);
                                     lock(&(&k->k_lock)->rlock);
        <Interrupt>
          lock(&(&ha->tgt.sess_lock)->rlock);
      
       *** DEADLOCK ***
      
      3 locks held by kworker/2:1/62:
       #0: 00000000a4319c16 ((wq_completion)"qla2xxx_wq"){+.+.}, at: process_one_work+0x437/0xa80
       #1: 00000000ffa34c42 ((work_completion)(&sess->del_work)){+.+.}, at: process_one_work+0x437/0xa80
       #2: 00000000a033b71c (&(&ha->tgt.sess_lock)->rlock){-...}, at: qla24xx_delete_sess_fn+0x55/0xf0 [qla2xxx_scst]
      
      the dependencies between HARDIRQ-irq-safe lock and the holding lock:
      -> (&(&ha->tgt.sess_lock)->rlock){-...} ops: 8 {
         IN-HARDIRQ-W at:
                          lock_acquire+0xe3/0x200
                          _raw_spin_lock_irqsave+0x3d/0x60
                          qla24xx_report_id_acquisition+0xa69/0xe30 [qla2xxx_scst]
                          qla24xx_process_response_queue+0x69e/0x1270 [qla2xxx_scst]
                          qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx_scst]
                          __handle_irq_event_percpu+0x79/0x3c0
                          handle_irq_event_percpu+0x70/0xf0
                          handle_irq_event+0x5a/0x8b
                          handle_edge_irq+0x12c/0x310
                          handle_irq+0x192/0x20a
                          do_IRQ+0x73/0x160
                          ret_from_intr+0x0/0x1d
                          default_idle+0x23/0x1f0
                          arch_cpu_idle+0x15/0x20
                          default_idle_call+0x35/0x40
                          do_idle+0x2bb/0x2e0
                          cpu_startup_entry+0x1d/0x20
                          start_secondary+0x2a8/0x320
                          secondary_startup_64+0xa4/0xb0
         INITIAL USE at:
                         lock_acquire+0xe3/0x200
                         _raw_spin_lock_irqsave+0x3d/0x60
                         qla24xx_report_id_acquisition+0xa69/0xe30 [qla2xxx_scst]
                         qla24xx_process_response_queue+0x69e/0x1270 [qla2xxx_scst]
                         qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx_scst]
                         __handle_irq_event_percpu+0x79/0x3c0
                         handle_irq_event_percpu+0x70/0xf0
                         handle_irq_event+0x5a/0x8b
                         handle_edge_irq+0x12c/0x310
                         handle_irq+0x192/0x20a
                         do_IRQ+0x73/0x160
                         ret_from_intr+0x0/0x1d
                         default_idle+0x23/0x1f0
                         arch_cpu_idle+0x15/0x20
                         default_idle_call+0x35/0x40
                         do_idle+0x2bb/0x2e0
                         cpu_startup_entry+0x1d/0x20
                         start_secondary+0x2a8/0x320
                         secondary_startup_64+0xa4/0xb0
       }
       ... key      at: [<ffffffffa0c0d080>] __key.85462+0x0/0xfffffffffff7df80 [qla2xxx_scst]
       ... acquired at:
         lock_acquire+0xe3/0x200
         _raw_spin_lock_irqsave+0x3d/0x60
         klist_next+0x43/0x1d0
         device_for_each_child+0x96/0x110
         scsi_target_block+0x3c/0x40 [scsi_mod]
         fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
         qla2x00_mark_device_lost+0xa0b/0xa30 [qla2xxx_scst]
         qlt_unreg_sess+0x1c6/0x380 [qla2xxx_scst]
         qla24xx_delete_sess_fn+0xe6/0xf0 [qla2xxx_scst]
         process_one_work+0x511/0xa80
         worker_thread+0x67/0x5b0
         kthread+0x1d2/0x1f0
         ret_from_fork+0x3a/0x50
      
      the dependencies between the lock to be acquired
       and HARDIRQ-irq-unsafe lock:
      -> (&(&k->k_lock)->rlock){+.+.} ops: 13831 {
         HARDIRQ-ON-W at:
                          lock_acquire+0xe3/0x200
                          _raw_spin_lock+0x32/0x50
                          klist_add_tail+0x33/0xb0
                          device_add+0x7e1/0xb50
                          device_create_groups_vargs+0x11c/0x150
                          device_create_with_groups+0x89/0xb0
                          vtconsole_class_init+0xb2/0x124
                          do_one_initcall+0xc5/0x3ce
                          kernel_init_freeable+0x295/0x32e
                          kernel_init+0x11/0x11b
                          ret_from_fork+0x3a/0x50
         SOFTIRQ-ON-W at:
                          lock_acquire+0xe3/0x200
                          _raw_spin_lock+0x32/0x50
                          klist_add_tail+0x33/0xb0
                          device_add+0x7e1/0xb50
                          device_create_groups_vargs+0x11c/0x150
                          device_create_with_groups+0x89/0xb0
                          vtconsole_class_init+0xb2/0x124
                          do_one_initcall+0xc5/0x3ce
                          kernel_init_freeable+0x295/0x32e
                          kernel_init+0x11/0x11b
                          ret_from_fork+0x3a/0x50
         INITIAL USE at:
                         lock_acquire+0xe3/0x200
                         _raw_spin_lock+0x32/0x50
                         klist_add_tail+0x33/0xb0
                         device_add+0x7e1/0xb50
                         device_create_groups_vargs+0x11c/0x150
                         device_create_with_groups+0x89/0xb0
                         vtconsole_class_init+0xb2/0x124
                         do_one_initcall+0xc5/0x3ce
                         kernel_init_freeable+0x295/0x32e
                         kernel_init+0x11/0x11b
                         ret_from_fork+0x3a/0x50
       }
       ... key      at: [<ffffffff83ed8780>] __key.15491+0x0/0x40
       ... acquired at:
         lock_acquire+0xe3/0x200
         _raw_spin_lock_irqsave+0x3d/0x60
         klist_next+0x43/0x1d0
         device_for_each_child+0x96/0x110
         scsi_target_block+0x3c/0x40 [scsi_mod]
         fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
         qla2x00_mark_device_lost+0xa0b/0xa30 [qla2xxx_scst]
         qlt_unreg_sess+0x1c6/0x380 [qla2xxx_scst]
         qla24xx_delete_sess_fn+0xe6/0xf0 [qla2xxx_scst]
         process_one_work+0x511/0xa80
         worker_thread+0x67/0x5b0
         kthread+0x1d2/0x1f0
         ret_from_fork+0x3a/0x50
      
      stack backtrace:
      CPU: 2 PID: 62 Comm: kworker/2:1 Tainted: G           O      5.0.7-dbg+ #8
      Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
      Workqueue: qla2xxx_wq qla24xx_delete_sess_fn [qla2xxx_scst]
      Call Trace:
       dump_stack+0x86/0xca
       check_usage.cold.52+0x473/0x563
       __lock_acquire+0x11c0/0x23e0
       lock_acquire+0xe3/0x200
       _raw_spin_lock_irqsave+0x3d/0x60
       klist_next+0x43/0x1d0
       device_for_each_child+0x96/0x110
       scsi_target_block+0x3c/0x40 [scsi_mod]
       fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
       qla2x00_mark_device_lost+0xa0b/0xa30 [qla2xxx_scst]
       qlt_unreg_sess+0x1c6/0x380 [qla2xxx_scst]
       qla24xx_delete_sess_fn+0xe6/0xf0 [qla2xxx_scst]
       process_one_work+0x511/0xa80
       worker_thread+0x67/0x5b0
       kthread+0x1d2/0x1f0
       ret_from_fork+0x3a/0x50
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      300ec741
    • Bart Van Assche's avatar
      scsi: qla2xxx: Complain loudly about reference count underflow · db4bf822
      Bart Van Assche authored
      A reference count underflow is a severe bug. Hence complain loudly if a
      reference count underflow happens.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      db4bf822
    • Bart Van Assche's avatar
      scsi: qla2xxx: Use __le64 instead of uint32_t[2] for sending DMA addresses to firmware · d4556a49
      Bart Van Assche authored
      This patch makes the code easier to read and more compact.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      d4556a49
    • Bart Van Assche's avatar
      scsi: qla2xxx: Introduce the dsd32 and dsd64 data structures · 15b7a68c
      Bart Van Assche authored
      Introduce two structures for the (DMA address, length) combination instead
      of using separate structure members for the DMA address and length. This
      patch fixes several Coverity complaints about 'cur_dsd' being used to write
      outside the bounds of structure members.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      15b7a68c
    • Bart Van Assche's avatar
      scsi: qla2xxx: Check the size of firmware data structures at compile time · bc04459c
      Bart Van Assche authored
      Since the next patch will modify several firmware data structures, add
      compile time checks that verify that these structures have the correct
      size.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      bc04459c
    • Bart Van Assche's avatar
      scsi: qla2xxx: Pass little-endian values to the firmware · 6e73985a
      Bart Van Assche authored
      Pass dsd_list_len in little endian format to the firmware instead of in CPU
      endian format.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      6e73985a
    • Bart Van Assche's avatar
      scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands · 219d27d7
      Bart Van Assche authored
      In the *_done() functions, instead of returning early if sp->ref_count >=
      2, only decrement sp->ref_count. In qla2xxx_eh_abort(), instead of deciding
      what to do based on the value of sp->ref_count, decide which action to take
      depending on the completion status of the firmware abort. Remove srb.cwaitq
      and use srb.comp instead. In qla2x00_abort_srb(), call
      isp_ops->abort_command() directly instead of calling qla2xxx_eh_abort().
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      219d27d7
    • Bart Van Assche's avatar
      scsi: qla2xxx: Use an on-stack completion in qla24xx_control_vp() · 982cc4be
      Bart Van Assche authored
      This patch reduces the size of struct srb.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      982cc4be
    • Bart Van Assche's avatar
      scsi: qla2xxx: Make qla24xx_async_abort_cmd() static · 1956eee5
      Bart Van Assche authored
      Since qla24xx_async_abort_cmd() is only called from inside qla_init.c,
      declare that function static. Reorder a few functions to avoid that any
      forward declarations are needed.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      1956eee5
    • Bart Van Assche's avatar
      scsi: qla2xxx: Remove unnecessary locking from the target code · 1b1e68d2
      Bart Van Assche authored
      All callbacks from the target core into the qla2xxx driver and also all I/O
      completion functions are serialized per command. Since .cmd_sent_to_fw and
      .trc_flags are only modified from inside these functions it is not
      necessary to protect it with locking. Remove the superfluous locking.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      1b1e68d2
    • Bart Van Assche's avatar
      scsi: qla2xxx: Remove qla_tgt_cmd.released · 4c374596
      Bart Van Assche authored
      Since the previous patch removed the only statement that sets
      qla_tgt_cmd.released, remove the code that depends on that member variable
      being set and the member variable itself.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      4c374596
    • Bart Van Assche's avatar
      scsi: qla2xxx: Complain if a command is released that is owned by the firmware · b1e261d4
      Bart Van Assche authored
      The previous patch guarantees that a command is only released after the
      firmware has finished processing it. Hence complain if a command is
      released that is owned by the firmware.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      b1e261d4
    • Bart Van Assche's avatar
      scsi: qla2xxx: target: Fix offline port handling and host reset handling · aefed3e5
      Bart Van Assche authored
      Remove the function qlt_abort_cmd_on_host_reset() because it can do the
      following, all of which can cause a kernel crash:
      
      - DMA unmapping while DMA is in progress.
      - Call target_execute_cmd() while DMA is in progress.
      - Call transport_generic_free_cmd() while the LIO core owns a command.
      
      Instead of trying to abort a command asynchronously, set the 'aborted' flag
      and handle the abort after the hardware has passed control back to the
      tcm_qla2xxx driver.
      
      Cc: Arun Easi <arun.easi@qlogic.com>
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Fixes: c0cb4496 ("qla2xxx: Add Host reset handling in target mode.") # v3.18.
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      aefed3e5
    • Bart Van Assche's avatar
      scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending() · e209783d
      Bart Van Assche authored
      Implementations of the .write_pending() callback functions must guarantee
      that an appropriate LIO core callback function will be called immediately or
      at a later time.  Make sure that this guarantee is met for aborted SCSI
      commands.
      
      [mkp: typo]
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Fixes: 694833ee ("scsi: tcm_qla2xxx: Do not allow aborted cmd to advance.") # v4.13.
      Fixes: a07100e0 ("qla2xxx: Fix TMR ABORT interaction issue between qla2xxx and TCM") # v4.5.
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      e209783d
    • Bart Van Assche's avatar
      scsi: qla2xxx: Fix error handling in qlt_alloc_qfull_cmd() · c04466c1
      Bart Van Assche authored
      The test "if (!cmd)" is not useful because it is guaranteed that cmd !=
      NULL.  Instead of testing the cmd pointer, rely on the tag to decide
      whether or not command allocation failed.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Fixes: 33e79977 ("qla2xxx: Add support for QFull throttling and Term Exchange retry") # v3.18.
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      c04466c1
    • Bart Van Assche's avatar
      scsi: qla2xxx: Simplify qlt_send_term_imm_notif() · e65449aa
      Bart Van Assche authored
      All qlt_send_term_imm_notif() callers pass '1' as second argument to this
      function. Hence remove the (broken) code that depends on that second
      argument having another value. Add a pr_debug() statement that prints rc to
      avoid that the compiler would complain that rc has been set but is not
      used.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      e65449aa
    • Bart Van Assche's avatar
      scsi: qla2xxx: Fix use-after-free issues in qla2xxx_qpair_sp_free_dma() · d8f945bf
      Bart Van Assche authored
      The current order for freeing memory is as follows:
      - struct crc_context itself.
      - struct crc_context member pointers.
      
      Change the freeing order into the following:
      - struct crc_context member pointers.
      - struct crc_context itself.
      
      Detected by Coverity.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Fixes: 50b81275 ("scsi: qla2xxx: Fix DMA error when the DIF sg buffer crosses 4GB boundary") # v5.1-rc1.
      Fixes: d7459527 ("scsi: qla2xxx: Add multiple queue pair functionality.") # v4.10.
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      d8f945bf
    • Bart Van Assche's avatar
      scsi: qla2xxx: Fix a qla24xx_enable_msix() error path · 24afabdb
      Bart Van Assche authored
      Make sure that the allocated interrupts are freed if allocating memory for
      the msix_entries array fails.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      24afabdb
    • Bart Van Assche's avatar
      scsi: qla2xxx: Avoid that qla2x00_mem_free() crashes if called twice · dc035d4e
      Bart Van Assche authored
      Clear each pointer after having freed memory such that it becomes safe to
      call qla2x00_mem_free() twice.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      dc035d4e
    • Bart Van Assche's avatar
      scsi: qla2xxx: Make qla2x00_mem_free() easier to verify · 5365bf99
      Bart Van Assche authored
      Instead of clearing all freed pointers at the end of qla2x00_mem_free(),
      clear freed pointers immediately after having freed the memory these
      pointers point at.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      5365bf99
    • Bart Van Assche's avatar
      scsi: qla2xxx: Increase the size of the mailbox arrays from 4 to 8 · 0a59cea4
      Bart Van Assche authored
      This patch avoids that Coverity complains that qla2x00_async_event() writes
      outside the bounds of the mb[] arrays (MBA_IDC_AEN case).
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      0a59cea4
    • Bart Van Assche's avatar
      scsi: qla2xxx: Log the status code if a firmware command fails · 3f918ffa
      Bart Van Assche authored
      It is important to know why a firmware command failed. Hence log 'rval'
      together with the values of the mailbox registers if a firwmare command
      fails.
      
      Cc: Himanshu Madhani <hmadhani@marvell.com>
      Cc: Giridhar Malavali <gmalavali@marvell.com>
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
      Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
      3f918ffa