summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_internal.h
diff options
context:
space:
mode:
authorDan Williams2012-03-09 20:00:06 +0100
committerJames Bottomley2012-04-23 13:03:39 +0200
commit22b9153faa2263aa89625de25e71c7d44c8dbd16 (patch)
tree1157d64a9c63c5b7b48b4a5b3610965d8d4c9624 /drivers/scsi/libsas/sas_internal.h
parent[SCSI] libata: Pass correct DMA device to scsi host (diff)
downloadkernel-qcow2-linux-22b9153faa2263aa89625de25e71c7d44c8dbd16.tar.gz
kernel-qcow2-linux-22b9153faa2263aa89625de25e71c7d44c8dbd16.tar.xz
kernel-qcow2-linux-22b9153faa2263aa89625de25e71c7d44c8dbd16.zip
[SCSI] libsas: introduce sas_work to fix sas_drain_work vs sas_queue_work
When requeuing work to a draining workqueue the last work instance may not be idle, so sas_queue_work() must not touch work->entry. Introduce sas_work with a drain_node list_head to have a private list for collecting work deferred due to drain collision. Fixes reports like: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<ffffffff810410d4>] process_one_work+0x2e/0x338 Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_internal.h')
-rw-r--r--drivers/scsi/libsas/sas_internal.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index f05c63879949..507e4cf12e56 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -45,10 +45,10 @@ struct sas_phy_data {
struct mutex event_lock;
int hard_reset;
int reset_result;
- struct work_struct reset_work;
+ struct sas_work reset_work;
int enable;
int enable_result;
- struct work_struct enable_work;
+ struct sas_work enable_work;
};
void sas_scsi_recover_host(struct Scsi_Host *shost);
@@ -80,7 +80,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work);
void sas_porte_link_reset_err(struct work_struct *work);
void sas_porte_timer_event(struct work_struct *work);
void sas_porte_hard_reset(struct work_struct *work);
-void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work);
+void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw);
int sas_notify_lldd_dev_found(struct domain_device *);
void sas_notify_lldd_dev_gone(struct domain_device *);