1. 05 3月, 2021 1 次提交
  2. 09 2月, 2021 6 次提交
    • M
      scsi: libiscsi: Reset max/exp cmdsn during recovery · c8447e4c
      Mike Christie 提交于
      If we lose the session then relogin, but the new cmdsn window has shrunk
      (due to something like an admin changing a setting) we will have the old
      exp/max_cmdsn values and will never be able to update them. For example,
      max_cmdsn would be 64, but if on the target the user set the window to be
      smaller then the target could try to return the max_cmdsn as 32. We will
      see that new max_cmdsn in the rsp but because it's lower than the old
      max_cmdsn when the window was larger we will not update it.
      
      So this patch has us reset the window values during session cleanup so they
      can be updated after a new login.
      
      Link: https://lore.kernel.org/r/20210207044608.27585-8-michael.christie@oracle.comReviewed-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMike Christie <michael.christie@oracle.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      c8447e4c
    • M
      scsi: libiscsi: Add helper to calculate max SCSI cmds per session · b4046922
      Mike Christie 提交于
      This patch just breaks out the code that calculates the number of SCSI cmds
      that will be used for a SCSI session. It also adds a check that we don't go
      over the host's can_queue value.
      
      Link: https://lore.kernel.org/r/20210207044608.27585-6-michael.christie@oracle.comReviewed-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMike Christie <michael.christie@oracle.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      b4046922
    • M
      scsi: libiscsi: Fix iSCSI host workq destruction · c435f0a9
      Mike Christie 提交于
      We allocate the iSCSI host workq in iscsi_host_alloc() so iscsi_host_free()
      should do the destruction. Drivers can then do their error/goto handling
      and call iscsi_host_free() to clean up what has been allocated in
      iscsi_host_alloc().
      
      Link: https://lore.kernel.org/r/20210207044608.27585-5-michael.christie@oracle.comReviewed-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMike Christie <michael.christie@oracle.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      c435f0a9
    • M
      scsi: libiscsi: Fix iscsi_task use after free() · 14936b1e
      Mike Christie 提交于
      The following bug was reported and debugged by wubo40@huawei.com:
      
      When testing kernel 4.18 version, NULL pointer dereference problem occurs
      in iscsi_eh_cmd_timed_out() function.
      
      I think this bug in the upstream is still exists.
      
      The analysis reasons are as follows:
      
      1) For some reason, I/O command did not complete within the timeout
         period. The block layer timer works, call scsi_times_out() to handle I/O
         timeout logic.  At the same time the command just completes.
      
      2) scsi_times_out() call iscsi_eh_cmd_timed_out() to process timeout logic.
         Although there is an NULL judgment for the task, the task has not been
         released yet now.
      
      3) iscsi_complete_task() calls __iscsi_put_task(). The task reference count
         reaches zero, the conditions for free task is met, then
         iscsi_free_task() frees the task, and sets sc->SCp.ptr = NULL. After
         iscsi_eh_cmd_timed_out() passes the task judgment check, there can still
         be NULL dereference scenarios.
      
         CPU0                                                CPU3
      
          |- scsi_times_out()                                 |-
      iscsi_complete_task()
          |                                                   |
          |- iscsi_eh_cmd_timed_out()                         |-
      __iscsi_put_task()
          |                                                   |
          |- task=sc->SCp.ptr, task is not NUL, check passed  |-
      iscsi_free_task(task)
          |                                                   |
          |                                                   |-> sc->SCp.ptr
      = NULL
          |                                                   |
          |- task is NULL now, NULL pointer dereference       |
          |                                                   |
         \|/                                                 \|/
      
      Calltrace:
      [380751.840862] BUG: unable to handle kernel NULL pointer dereference at
      0000000000000138
      [380751.843709] PGD 0 P4D 0
      [380751.844770] Oops: 0000 [#1] SMP PTI
      [380751.846283] CPU: 0 PID: 403 Comm: kworker/0:1H Kdump: loaded
      Tainted: G
      [380751.851467] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
      [380751.856521] Workqueue: kblockd blk_mq_timeout_work
      [380751.858527] RIP: 0010:iscsi_eh_cmd_timed_out+0x15e/0x2e0 [libiscsi]
      [380751.861129] Code: 83 ea 01 48 8d 74 d0 08 48 8b 10 48 8b 4a 50 48 85
      c9 74 2c 48 39 d5 74
      [380751.868811] RSP: 0018:ffffc1e280a5fd58 EFLAGS: 00010246
      [380751.870978] RAX: ffff9fd1e84e15e0 RBX: ffff9fd1e84e6dd0 RCX:
      0000000116acc580
      [380751.873791] RDX: ffff9fd1f97a9400 RSI: ffff9fd1e84e1800 RDI:
      ffff9fd1e4d6d420
      [380751.876059] RBP: ffff9fd1e4d49000 R08: 0000000116acc580 R09:
      0000000116acc580
      [380751.878284] R10: 0000000000000000 R11: 0000000000000000 R12:
      ffff9fd1e6e931e8
      [380751.880500] R13: ffff9fd1e84e6ee0 R14: 0000000000000010 R15:
      0000000000000003
      [380751.882687] FS:  0000000000000000(0000) GS:ffff9fd1fac00000(0000)
      knlGS:0000000000000000
      [380751.885236] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [380751.887059] CR2: 0000000000000138 CR3: 000000011860a001 CR4:
      00000000003606f0
      [380751.889308] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
      0000000000000000
      [380751.891523] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7:
      0000000000000400
      [380751.893738] Call Trace:
      [380751.894639]  scsi_times_out+0x60/0x1c0
      [380751.895861]  blk_mq_check_expired+0x144/0x200
      [380751.897302]  ? __switch_to_asm+0x35/0x70
      [380751.898551]  blk_mq_queue_tag_busy_iter+0x195/0x2e0
      [380751.900091]  ? __blk_mq_requeue_request+0x100/0x100
      [380751.901611]  ? __switch_to_asm+0x41/0x70
      [380751.902853]  ? __blk_mq_requeue_request+0x100/0x100
      [380751.904398]  blk_mq_timeout_work+0x54/0x130
      [380751.905740]  process_one_work+0x195/0x390
      [380751.907228]  worker_thread+0x30/0x390
      [380751.908713]  ? process_one_work+0x390/0x390
      [380751.910350]  kthread+0x10d/0x130
      [380751.911470]  ? kthread_flush_work_fn+0x10/0x10
      [380751.913007]  ret_from_fork+0x35/0x40
      
      crash> dis -l iscsi_eh_cmd_timed_out+0x15e
      xxxxx/drivers/scsi/libiscsi.c: 2062
      
      1970 enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd
      *sc)
      {
      ...
      1984         spin_lock_bh(&session->frwd_lock);
      1985         task = (struct iscsi_task *)sc->SCp.ptr;
      1986         if (!task) {
      1987                 /*
      1988                  * Raced with completion. Blk layer has taken
      ownership
      1989                  * so let timeout code complete it now.
      1990                  */
      1991                 rc = BLK_EH_DONE;
      1992                 goto done;
      1993         }
      
      ...
      
      2052         for (i = 0; i < conn->session->cmds_max; i++) {
      2053                 running_task = conn->session->cmds[i];
      2054                 if (!running_task->sc || running_task == task ||
      2055                      running_task->state != ISCSI_TASK_RUNNING)
      2056                         continue;
      2057
      2058                 /*
      2059                  * Only check if cmds started before this one have
      made
      2060                  * progress, or this could never fail
      2061                  */
      2062                 if (time_after(running_task->sc->jiffies_at_alloc,
      2063                                task->sc->jiffies_at_alloc))    <---
      2064                         continue;
      2065
      ...
      }
      
      carsh> struct scsi_cmnd ffff9fd1e6e931e8
      struct scsi_cmnd {
        ...
        SCp = {
          ptr = 0x0,   <--- iscsi_task
          this_residual = 0,
          ...
        },
      }
      
      To prevent this, we take a ref to the cmd under the back (completion) lock
      so if the completion side were to call iscsi_complete_task() on the task
      while the timer/eh paths are not holding the back_lock it will not be freed
      from under us.
      
      Note that this requires the previous patch, "scsi: libiscsi: Drop
      taskqueuelock" because bnx2i sleeps in its cleanup_task callout if the cmd
      is aborted. If the EH/timer and completion path are racing we don't know
      which path will do the last put. The previous patch moved the operations we
      needed to do under the forward lock to cleanup_queued_task.  Once that has
      run we can drop the forward lock for the cmd and bnx2i no longer has to
      worry about if the EH, timer or completion path did the ast put and if the
      forward lock is held or not since it won't be.
      
      Link: https://lore.kernel.org/r/20210207044608.27585-4-michael.christie@oracle.comReported-by: NWu Bo <wubo40@huawei.com>
      Reviewed-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMike Christie <michael.christie@oracle.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      14936b1e
    • M
      scsi: libiscsi: Drop taskqueuelock · 5923d64b
      Mike Christie 提交于
      The purpose of the taskqueuelock was to handle the issue where a bad target
      decides to send a R2T and before its data has been sent decides to send a
      cmd response to complete the cmd. The following patches fix up the
      frwd/back locks so they are taken from the queue/xmit (frwd) and completion
      (back) paths again. To get there this patch removes the taskqueuelock which
      for iSCSI xmit wq based drivers was taken in the queue, xmit and completion
      paths.
      
      Instead of the lock, we just make sure we have a ref to the task when we
      queue a R2T, and then we always remove the task from the requeue list in
      the xmit path or the forced cleanup paths.
      
      Link: https://lore.kernel.org/r/20210207044608.27585-3-michael.christie@oracle.comReviewed-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMike Christie <michael.christie@oracle.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      5923d64b
    • M
      scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling · d28d48c6
      Mike Christie 提交于
      If iscsi_prep_scsi_cmd_pdu() fails we try to add it back to the cmdqueue,
      but we leave it partially setup. We don't have functions that can undo the
      pdu and init task setup. We only have cleanup_task which can clean up both
      parts. So this has us just fail the cmd and go through the standard cleanup
      routine and then have the SCSI midlayer retry it like is done when it fails
      in the queuecommand path.
      
      Link: https://lore.kernel.org/r/20210207044608.27585-2-michael.christie@oracle.comReviewed-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMike Christie <michael.christie@oracle.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      d28d48c6
  3. 17 11月, 2020 1 次提交
  4. 27 10月, 2020 1 次提交
  5. 24 8月, 2020 1 次提交
  6. 03 7月, 2020 1 次提交
  7. 27 5月, 2020 1 次提交
  8. 27 3月, 2020 2 次提交
  9. 10 12月, 2019 1 次提交
    • B
      scsi: iscsi: Fix a potential deadlock in the timeout handler · 5480e299
      Bart Van Assche 提交于
      Some time ago the block layer was modified such that timeout handlers are
      called from thread context instead of interrupt context. Make it safe to
      run the iSCSI timeout handler in thread context. This patch fixes the
      following lockdep complaint:
      
      ================================
      WARNING: inconsistent lock state
      5.5.1-dbg+ #11 Not tainted
      --------------------------------
      inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
      kworker/7:1H/206 [HC0[0]:SC0[0]:HE1:SE1] takes:
      ffff88802d9827e8 (&(&session->frwd_lock)->rlock){+.?.}, at: iscsi_eh_cmd_timed_out+0xa6/0x6d0 [libiscsi]
      {IN-SOFTIRQ-W} state was registered at:
        lock_acquire+0x106/0x240
        _raw_spin_lock+0x38/0x50
        iscsi_check_transport_timeouts+0x3e/0x210 [libiscsi]
        call_timer_fn+0x132/0x470
        __run_timers.part.0+0x39f/0x5b0
        run_timer_softirq+0x63/0xc0
        __do_softirq+0x12d/0x5fd
        irq_exit+0xb3/0x110
        smp_apic_timer_interrupt+0x131/0x3d0
        apic_timer_interrupt+0xf/0x20
        default_idle+0x31/0x230
        arch_cpu_idle+0x13/0x20
        default_idle_call+0x53/0x60
        do_idle+0x38a/0x3f0
        cpu_startup_entry+0x24/0x30
        start_secondary+0x222/0x290
        secondary_startup_64+0xa4/0xb0
      irq event stamp: 1383705
      hardirqs last  enabled at (1383705): [<ffffffff81aace5c>] _raw_spin_unlock_irq+0x2c/0x50
      hardirqs last disabled at (1383704): [<ffffffff81aacb98>] _raw_spin_lock_irq+0x18/0x50
      softirqs last  enabled at (1383690): [<ffffffffa0e2efea>] iscsi_queuecommand+0x76a/0xa20 [libiscsi]
      softirqs last disabled at (1383682): [<ffffffffa0e2e998>] iscsi_queuecommand+0x118/0xa20 [libiscsi]
      
      other info that might help us debug this:
       Possible unsafe locking scenario:
      
             CPU0
             ----
        lock(&(&session->frwd_lock)->rlock);
        <Interrupt>
          lock(&(&session->frwd_lock)->rlock);
      
       *** DEADLOCK ***
      
      2 locks held by kworker/7:1H/206:
       #0: ffff8880d57bf928 ((wq_completion)kblockd){+.+.}, at: process_one_work+0x472/0xab0
       #1: ffff88802b9c7de8 ((work_completion)(&q->timeout_work)){+.+.}, at: process_one_work+0x476/0xab0
      
      stack backtrace:
      CPU: 7 PID: 206 Comm: kworker/7:1H Not tainted 5.5.1-dbg+ #11
      Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
      Workqueue: kblockd blk_mq_timeout_work
      Call Trace:
       dump_stack+0xa5/0xe6
       print_usage_bug.cold+0x232/0x23b
       mark_lock+0x8dc/0xa70
       __lock_acquire+0xcea/0x2af0
       lock_acquire+0x106/0x240
       _raw_spin_lock+0x38/0x50
       iscsi_eh_cmd_timed_out+0xa6/0x6d0 [libiscsi]
       scsi_times_out+0xf4/0x440 [scsi_mod]
       scsi_timeout+0x1d/0x20 [scsi_mod]
       blk_mq_check_expired+0x365/0x3a0
       bt_iter+0xd6/0xf0
       blk_mq_queue_tag_busy_iter+0x3de/0x650
       blk_mq_timeout_work+0x1af/0x380
       process_one_work+0x56d/0xab0
       worker_thread+0x7a/0x5d0
       kthread+0x1bc/0x210
       ret_from_fork+0x24/0x30
      
      Fixes: 287922eb ("block: defer timeouts to a workqueue")
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Keith Busch <keith.busch@intel.com>
      Cc: Lee Duncan <lduncan@suse.com>
      Cc: Chris Leech <cleech@redhat.com>
      Cc: <stable@vger.kernel.org>
      Link: https://lore.kernel.org/r/20191209173457.187370-1-bvanassche@acm.orgSigned-off-by: NBart Van Assche <bvanassche@acm.org>
      Reviewed-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      5480e299
  10. 31 5月, 2019 1 次提交
  11. 21 5月, 2019 1 次提交
  12. 08 3月, 2019 1 次提交
  13. 16 2月, 2019 1 次提交
    • A
      scsi: libiscsi: Fix race between iscsi_xmit_task and iscsi_complete_task · 79edd00d
      Anoob Soman 提交于
      When a target sends Check Condition, whilst initiator is busy xmiting
      re-queued data, could lead to race between iscsi_complete_task() and
      iscsi_xmit_task() and eventually crashing with the following kernel
      backtrace.
      
      [3326150.987523] ALERT: BUG: unable to handle kernel NULL pointer dereference at 0000000000000078
      [3326150.987549] ALERT: IP: [<ffffffffa05ce70d>] iscsi_xmit_task+0x2d/0xc0 [libiscsi]
      [3326150.987571] WARN: PGD 569c8067 PUD 569c9067 PMD 0
      [3326150.987582] WARN: Oops: 0002 [#1] SMP
      [3326150.987593] WARN: Modules linked in: tun nfsv3 nfs fscache dm_round_robin
      [3326150.987762] WARN: CPU: 2 PID: 8399 Comm: kworker/u32:1 Tainted: G O 4.4.0+2 #1
      [3326150.987774] WARN: Hardware name: Dell Inc. PowerEdge R720/0W7JN5, BIOS 2.5.4 01/22/2016
      [3326150.987790] WARN: Workqueue: iscsi_q_13 iscsi_xmitworker [libiscsi]
      [3326150.987799] WARN: task: ffff8801d50f3800 ti: ffff8801f5458000 task.ti: ffff8801f5458000
      [3326150.987810] WARN: RIP: e030:[<ffffffffa05ce70d>] [<ffffffffa05ce70d>] iscsi_xmit_task+0x2d/0xc0 [libiscsi]
      [3326150.987825] WARN: RSP: e02b:ffff8801f545bdb0 EFLAGS: 00010246
      [3326150.987831] WARN: RAX: 00000000ffffffc3 RBX: ffff880282d2ab20 RCX: ffff88026b6ac480
      [3326150.987842] WARN: RDX: 0000000000000000 RSI: 00000000fffffe01 RDI: ffff880282d2ab20
      [3326150.987852] WARN: RBP: ffff8801f545bdc8 R08: 0000000000000000 R09: 0000000000000008
      [3326150.987862] WARN: R10: 0000000000000000 R11: 000000000000fe88 R12: 0000000000000000
      [3326150.987872] WARN: R13: ffff880282d2abe8 R14: ffff880282d2abd8 R15: ffff880282d2ac08
      [3326150.987890] WARN: FS: 00007f5a866b4840(0000) GS:ffff88028a640000(0000) knlGS:0000000000000000
      [3326150.987900] WARN: CS: e033 DS: 0000 ES: 0000 CR0: 0000000080050033
      [3326150.987907] WARN: CR2: 0000000000000078 CR3: 0000000070244000 CR4: 0000000000042660
      [3326150.987918] WARN: Stack:
      [3326150.987924] WARN: ffff880282d2ad58 ffff880282d2ab20 ffff880282d2abe8 ffff8801f545be18
      [3326150.987938] WARN: ffffffffa05cea90 ffff880282d2abf8 ffff88026b59cc80 ffff88026b59cc00
      [3326150.987951] WARN: ffff88022acf32c0 ffff880289491800 ffff880255a80800 0000000000000400
      [3326150.987964] WARN: Call Trace:
      [3326150.987975] WARN: [<ffffffffa05cea90>] iscsi_xmitworker+0x2f0/0x360 [libiscsi]
      [3326150.987988] WARN: [<ffffffff8108862c>] process_one_work+0x1fc/0x3b0
      [3326150.987997] WARN: [<ffffffff81088f95>] worker_thread+0x2a5/0x470
      [3326150.988006] WARN: [<ffffffff8159cad8>] ? __schedule+0x648/0x870
      [3326150.988015] WARN: [<ffffffff81088cf0>] ? rescuer_thread+0x300/0x300
      [3326150.988023] WARN: [<ffffffff8108ddf5>] kthread+0xd5/0xe0
      [3326150.988031] WARN: [<ffffffff8108dd20>] ? kthread_stop+0x110/0x110
      [3326150.988040] WARN: [<ffffffff815a0bcf>] ret_from_fork+0x3f/0x70
      [3326150.988048] WARN: [<ffffffff8108dd20>] ? kthread_stop+0x110/0x110
      [3326150.988127] ALERT: RIP [<ffffffffa05ce70d>] iscsi_xmit_task+0x2d/0xc0 [libiscsi]
      [3326150.988138] WARN: RSP <ffff8801f545bdb0>
      [3326150.988144] WARN: CR2: 0000000000000078
      [3326151.020366] WARN: ---[ end trace 1c60974d4678d81b ]---
      
      Commit 6f8830f5 ("scsi: libiscsi: add lock around task lists to fix
      list corruption regression") introduced "taskqueuelock" to fix list
      corruption during the race, but this wasn't enough.
      
      Re-setting of conn->task to NULL, could race with iscsi_xmit_task().
      iscsi_complete_task()
      {
          ....
          if (conn->task == task)
              conn->task = NULL;
      }
      
      conn->task in iscsi_xmit_task() could be NULL and so will be task.
      __iscsi_get_task(task) will crash (NullPtr de-ref), trying to access
      refcount.
      
      iscsi_xmit_task()
      {
          struct iscsi_task *task = conn->task;
      
          __iscsi_get_task(task);
      }
      
      This commit will take extra conn->session->back_lock in iscsi_xmit_task()
      to ensure iscsi_xmit_task() waits for iscsi_complete_task(), if
      iscsi_complete_task() wins the race.  If iscsi_xmit_task() wins the race,
      iscsi_xmit_task() increments task->refcount
      (__iscsi_get_task) ensuring iscsi_complete_task() will not iscsi_free_task().
      Signed-off-by: NAnoob Soman <anoob.soman@citrix.com>
      Signed-off-by: NBob Liu <bob.liu@oracle.com>
      Acked-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      79edd00d
  14. 13 2月, 2019 1 次提交
  15. 06 2月, 2019 1 次提交
  16. 21 12月, 2018 1 次提交
  17. 29 11月, 2018 1 次提交
  18. 31 7月, 2018 2 次提交
  19. 13 7月, 2018 1 次提交
    • V
      scsi: libiscsi: fix possible NULL pointer dereference in case of TMF · a17037e7
      Varun Prakash 提交于
      In iscsi_check_tmf_restrictions() task->hdr is dereferenced to print the
      opcode, it is possible that task->hdr is NULL.
      
      There are two cases based on opcode argument:
      
      1. ISCSI_OP_SCSI_CMD - In this case alloc_pdu() is called
      after iscsi_check_tmf_restrictions()
      
      iscsi_prep_scsi_cmd_pdu() -> iscsi_check_tmf_restrictions() -> alloc_pdu().
      
      Transport drivers allocate memory for iSCSI hdr in alloc_pdu() and assign
      it to task->hdr. In case of TMF task->hdr will be NULL resulting in NULL
      pointer dereference.
      
      2. ISCSI_OP_SCSI_DATA_OUT - In this case transport driver can free the
      memory for iSCSI hdr after transmitting the pdu so task->hdr can be NULL or
      invalid.
      
      This patch fixes this issue by removing task->hdr->opcode from the printk
      statement.
      Signed-off-by: NVarun Prakash <varun@chelsio.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      a17037e7
  20. 13 6月, 2018 1 次提交
    • K
      treewide: kvzalloc() -> kvcalloc() · 778e1cdd
      Kees Cook 提交于
      The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
      patch replaces cases of:
      
              kvzalloc(a * b, gfp)
      
      with:
              kvcalloc(a * b, gfp)
      
      as well as handling cases of:
      
              kvzalloc(a * b * c, gfp)
      
      with:
      
              kvzalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kvcalloc(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kvzalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kvzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kvzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kvzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kvzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kvzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kvzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kvzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kvzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kvzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kvzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kvzalloc
      + kvcalloc
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kvzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kvzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kvzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kvzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kvzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kvzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kvzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kvzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kvzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kvzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kvzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kvzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kvzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kvzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kvzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kvzalloc(C1 * C2 * C3, ...)
      |
        kvzalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kvzalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kvzalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kvzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kvzalloc(sizeof(THING) * C2, ...)
      |
        kvzalloc(sizeof(TYPE) * C2, ...)
      |
        kvzalloc(C1 * C2 * C3, ...)
      |
        kvzalloc(C1 * C2, ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kvzalloc
      + kvcalloc
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      778e1cdd
  21. 29 5月, 2018 2 次提交
  22. 04 1月, 2018 2 次提交
    • R
      scsi: doc: fix iscsi-related kernel-doc warnings · ccd4a430
      Randy Dunlap 提交于
      Fix kernel-doc warnings in drivers/scsi/ that are related to iscsi
      support interfaces.
      
      Fixes these kernel-doc warnings: (tested by adding these files to a new
      target.rst documentation file: WIP)
      
      ../drivers/scsi/libiscsi.c:2740: warning: No description found for parameter 'dd_size'
      ../drivers/scsi/libiscsi.c:2740: warning: No description found for parameter 'id'
      ../drivers/scsi/libiscsi.c:2961: warning: No description found for parameter 'cls_conn'
      ../drivers/scsi/iscsi_tcp.c:313: warning: No description found for parameter 'conn'
      ../drivers/scsi/iscsi_tcp.c:363: warning: No description found for parameter 'conn'
      ../drivers/scsi/libiscsi_tcp.c:810: warning: No description found for parameter 'tcp_conn'
      ../drivers/scsi/libiscsi_tcp.c:810: warning: No description found for parameter 'segment'
      ../drivers/scsi/libiscsi_tcp.c:887: warning: No description found for parameter 'offloaded'
      ../drivers/scsi/libiscsi_tcp.c:887: warning: No description found for parameter 'status'
      ../drivers/scsi/libiscsi_tcp.c:887: warning: Excess function parameter 'offload' description in 'iscsi_tcp_recv_skb'
      ../drivers/scsi/libiscsi_tcp.c:964: warning: Excess function parameter 'conn' description in 'iscsi_tcp_task_init'
      ../drivers/scsi/libiscsi_tcp.c:964: warning: Excess function parameter 'sc' description in 'iscsi_tcp_task_init'
      Signed-off-by: NRandy Dunlap <rdunlap@infradead.org>
      Cc: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
      Cc: linux-scsi@vger.kernel.org
      Cc: target-devel@vger.kernel.org
      Cc: Sagi Grimberg <sagi@grimberg.me>
      Cc: linux-rdma@vger.kernel.org
      Cc: "James E.J. Bottomley" <jejb@linux.vnet.ibm.com>
      Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      ccd4a430
    • R
      scsi: libiscsi: Allow sd_shutdown on bad transport · d7549412
      Rafael David Tinoco 提交于
      If, for any reason, userland shuts down iscsi transport interfaces
      before proper logouts - like when logging in to LUNs manually, without
      logging out on server shutdown, or when automated scripts can't
      umount/logout from logged LUNs - kernel will hang forever on its
      sd_sync_cache() logic, after issuing the SYNCHRONIZE_CACHE cmd to all
      still existent paths.
      
      PID: 1 TASK: ffff8801a69b8000 CPU: 1 COMMAND: "systemd-shutdow"
       #0 [ffff8801a69c3a30] __schedule at ffffffff8183e9ee
       #1 [ffff8801a69c3a80] schedule at ffffffff8183f0d5
       #2 [ffff8801a69c3a98] schedule_timeout at ffffffff81842199
       #3 [ffff8801a69c3b40] io_schedule_timeout at ffffffff8183e604
       #4 [ffff8801a69c3b70] wait_for_completion_io_timeout at ffffffff8183fc6c
       #5 [ffff8801a69c3bd0] blk_execute_rq at ffffffff813cfe10
       #6 [ffff8801a69c3c88] scsi_execute at ffffffff815c3fc7
       #7 [ffff8801a69c3cc8] scsi_execute_req_flags at ffffffff815c60fe
       #8 [ffff8801a69c3d30] sd_sync_cache at ffffffff815d37d7
       #9 [ffff8801a69c3da8] sd_shutdown at ffffffff815d3c3c
      
      This happens because iscsi_eh_cmd_timed_out(), the transport layer
      timeout helper, would tell the queue timeout function (scsi_times_out)
      to reset the request timer over and over, until the session state is
      back to logged in state. Unfortunately, during server shutdown, this
      might never happen again.
      
      Other option would be "not to handle" the issue in the transport
      layer. That would trigger the error handler logic, which would also need
      the session state to be logged in again.
      
      Best option, for such case, is to tell upper layers that the command was
      handled during the transport layer error handler helper, marking it as
      DID_NO_CONNECT, which will allow completion and inform about the
      problem.
      
      After the session was marked as ISCSI_STATE_FAILED, due to the first
      timeout during the server shutdown phase, all subsequent cmds will fail
      to be queued, allowing upper logic to fail faster.
      Signed-off-by: NRafael David Tinoco <rafael.tinoco@canonical.com>
      Reviewed-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      d7549412
  23. 27 10月, 2017 1 次提交
  24. 12 10月, 2017 1 次提交
  25. 03 10月, 2017 1 次提交
  26. 26 8月, 2017 1 次提交
  27. 13 6月, 2017 1 次提交
    • K
      scsi: libiscsi: use kvzalloc for iscsi_pool_init · bfcc62ed
      Kyle Fortin 提交于
      iscsiadm session login can fail with the following error:
      
      iscsiadm: Could not login to [iface: default, target: iqn.1986-03.com...
      iscsiadm: initiator reported error (9 - internal error)
      
      When /etc/iscsi/iscsid.conf sets node.session.cmds_max = 4096, it
      results in 64K-sized kmallocs per session.  A system under fragmented
      slab pressure may not have any 64K objects available and fail iscsiadm
      session login. Even though memory objects of a smaller size are
      available, the large order allocation ends up failing.
      
      The kernel prints a warning and does dump_stack, like below:
      
      iscsid: page allocation failure: order:4, mode:0xc0d0
      CPU: 0 PID: 2456 Comm: iscsid Not tainted 4.1.12-61.1.28.el6uek.x86_64 #2
      Call Trace:
       [<ffffffff816c6e40>] dump_stack+0x63/0x83
       [<ffffffff8118e58a>] warn_alloc_failed+0xea/0x140
       [<ffffffff81191df9>] __alloc_pages_slowpath+0x409/0x760
       [<ffffffff81192401>] __alloc_pages_nodemask+0x2b1/0x2d0
       [<ffffffffa048f6c0>] ? dev_attr_host_ipaddress+0x20/0xffffffffffffc722
       [<ffffffff811dc38f>] alloc_pages_current+0xaf/0x170
       [<ffffffff81192581>] alloc_kmem_pages+0x31/0xd0
       [<ffffffffa048f600>] ? iscsi_transport_group+0x20/0xffffffffffffc7e2
       [<ffffffff811ad738>] kmalloc_order+0x18/0x50
       [<ffffffff811ad7a4>] kmalloc_order_trace+0x34/0xe0
       [<ffffffff8146ee30>] ? transport_remove_classdev+0x70/0x70
       [<ffffffff811e843d>] __kmalloc+0x27d/0x2a0
       [<ffffffff810c8cbd>] ? complete_all+0x4d/0x60
       [<ffffffffa04af299>] iscsi_pool_init+0x69/0x160 [libiscsi]
       [<ffffffff81465d90>] ? device_initialize+0xb0/0xd0
       [<ffffffffa04af510>] iscsi_session_setup+0x180/0x2f4 [libiscsi]
       [<ffffffffa04c5a60>] ? iscsi_max_lun+0x20/0xfffffffffffffa9e [iscsi_tcp]
       [<ffffffffa04c531f>] iscsi_sw_tcp_session_create+0xcf/0x150 [iscsi_tcp]
       [<ffffffffa04c5a60>] ? iscsi_max_lun+0x20/0xfffffffffffffa9e [iscsi_tcp]
       [<ffffffffa048a633>] iscsi_if_create_session+0x33/0xd0
       [<ffffffffa04c5a60>] ? iscsi_max_lun+0x20/0xfffffffffffffa9e [iscsi_tcp]
       [<ffffffffa048abd8>] iscsi_if_recv_msg+0x508/0x8c0 [scsi_transport_iscsi]
       [<ffffffff811922eb>] ? __alloc_pages_nodemask+0x19b/0x2d0
       [<ffffffff811e6d69>] ? __kmalloc_node_track_caller+0x209/0x2c0
       [<ffffffffa048b00c>] iscsi_if_rx+0x7c/0x200 [scsi_transport_iscsi]
       [<ffffffff81623dc6>] netlink_unicast+0x126/0x1c0
       [<ffffffff8162468c>] netlink_sendmsg+0x36c/0x400
       [<ffffffff815d2fed>] sock_sendmsg+0x4d/0x60
       [<ffffffff815d596a>] ___sys_sendmsg+0x30a/0x330
       [<ffffffff811bc72c>] ? handle_pte_fault+0x20c/0x230
       [<ffffffff811bc90c>] ? __handle_mm_fault+0x1bc/0x330
       [<ffffffff811bcb32>] ? handle_mm_fault+0xb2/0x1a0
       [<ffffffff815d5b99>] __sys_sendmsg+0x49/0x90
       [<ffffffff815d5bf9>] SyS_sendmsg+0x19/0x20
       [<ffffffff816cbb2e>] system_call_fastpath+0x12/0x71
      
      Use kvzalloc for iscsi_pool in iscsi_pool_init.
      Signed-off-by: NKyle Fortin <kyle.fortin@oracle.com>
      Tested-by: NKyle Fortin <kyle.fortin@oracle.com>
      Reviewed-by: NJoseph Slember <joe.slember@oracle.com>
      Reviewed-by: NLance Hartmann <lance.hartmann@oracle.com>
      Acked-by: NLee Duncan <lduncan@suse.com>
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      bfcc62ed
  28. 16 3月, 2017 1 次提交
  29. 02 3月, 2017 1 次提交
  30. 01 3月, 2017 1 次提交
    • C
      scsi: libiscsi: add lock around task lists to fix list corruption regression · 6f8830f5
      Chris Leech 提交于
      There's a rather long standing regression from the commit "libiscsi:
      Reduce locking contention in fast path"
      
      Depending on iSCSI target behavior, it's possible to hit the case in
      iscsi_complete_task where the task is still on a pending list
      (!list_empty(&task->running)).  When that happens the task is removed
      from the list while holding the session back_lock, but other task list
      modification occur under the frwd_lock.  That leads to linked list
      corruption and eventually a panicked system.
      
      Rather than back out the session lock split entirely, in order to try
      and keep some of the performance gains this patch adds another lock to
      maintain the task lists integrity.
      
      Major enterprise supported kernels have been backing out the lock split
      for while now, thanks to the efforts at IBM where a lab setup has the
      most reliable reproducer I've seen on this issue.  This patch has been
      tested there successfully.
      Signed-off-by: NChris Leech <cleech@redhat.com>
      Fixes: 659743b0 ("[SCSI] libiscsi: Reduce locking contention in fast path")
      Reported-by: NPrashantha Subbarao <psubbara@us.ibm.com>
      Reviewed-by: NGuilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
      Cc: <stable@vger.kernel.org> # v3.15+
      Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
      6f8830f5
  31. 07 2月, 2017 1 次提交