Commit d6834770 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "A couple of major (hang and deadlock) fixes with fortunately fairly
  rare triggering conditions.  The PM oops is only really triggered by
  people using enclosure services (rare) and the fnic driver is mostly
  used in enterprise environments"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  SCSI: Fix NULL pointer dereference in runtime PM
  fnic: Use the local variable instead of I/O flag to acquire io_req_lock in fnic_queuecommand() to avoid deadloack
parents eb63b34b 49718f0f
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#define DRV_NAME "fnic" #define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
#define DRV_VERSION "1.6.0.17" #define DRV_VERSION "1.6.0.17a"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: " #define DFX DRV_NAME "%d: "
......
...@@ -425,6 +425,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ ...@@ -425,6 +425,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
unsigned long ptr; unsigned long ptr;
struct fc_rport_priv *rdata; struct fc_rport_priv *rdata;
spinlock_t *io_lock = NULL; spinlock_t *io_lock = NULL;
int io_lock_acquired = 0;
if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED))) if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED)))
return SCSI_MLQUEUE_HOST_BUSY; return SCSI_MLQUEUE_HOST_BUSY;
...@@ -518,6 +519,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ ...@@ -518,6 +519,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
/* initialize rest of io_req */ /* initialize rest of io_req */
io_lock_acquired = 1;
io_req->port_id = rport->port_id; io_req->port_id = rport->port_id;
io_req->start_time = jiffies; io_req->start_time = jiffies;
CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING;
...@@ -571,7 +573,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ ...@@ -571,7 +573,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
(((u64)CMD_FLAGS(sc) >> 32) | CMD_STATE(sc))); (((u64)CMD_FLAGS(sc) >> 32) | CMD_STATE(sc)));
/* if only we issued IO, will we have the io lock */ /* if only we issued IO, will we have the io lock */
if (CMD_FLAGS(sc) & FNIC_IO_INITIALIZED) if (io_lock_acquired)
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
atomic_dec(&fnic->in_flight); atomic_dec(&fnic->in_flight);
......
...@@ -217,15 +217,15 @@ static int sdev_runtime_suspend(struct device *dev) ...@@ -217,15 +217,15 @@ static int sdev_runtime_suspend(struct device *dev)
{ {
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
struct scsi_device *sdev = to_scsi_device(dev); struct scsi_device *sdev = to_scsi_device(dev);
int err; int err = 0;
if (pm && pm->runtime_suspend) {
err = blk_pre_runtime_suspend(sdev->request_queue); err = blk_pre_runtime_suspend(sdev->request_queue);
if (err) if (err)
return err; return err;
if (pm && pm->runtime_suspend)
err = pm->runtime_suspend(dev); err = pm->runtime_suspend(dev);
blk_post_runtime_suspend(sdev->request_queue, err); blk_post_runtime_suspend(sdev->request_queue, err);
}
return err; return err;
} }
...@@ -248,11 +248,11 @@ static int sdev_runtime_resume(struct device *dev) ...@@ -248,11 +248,11 @@ static int sdev_runtime_resume(struct device *dev)
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int err = 0; int err = 0;
if (pm && pm->runtime_resume) {
blk_pre_runtime_resume(sdev->request_queue); blk_pre_runtime_resume(sdev->request_queue);
if (pm && pm->runtime_resume)
err = pm->runtime_resume(dev); err = pm->runtime_resume(dev);
blk_post_runtime_resume(sdev->request_queue, err); blk_post_runtime_resume(sdev->request_queue, err);
}
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment