@@ -989,8 +989,6 @@ static bool alua_rtpg_queue(struct alua_port_group *pg,
int start_queue = 0;
unsigned long flags;
- might_sleep();
-
if (WARN_ON_ONCE(!pg) || scsi_device_get(sdev))
return false;
@@ -1031,7 +1029,7 @@ static bool alua_rtpg_queue(struct alua_port_group *pg,
kref_put(&pg->kref, release_port_group);
}
if (sdev)
- scsi_device_put(sdev);
+ scsi_device_put_nosleep(sdev);
return true;
}
@@ -576,6 +576,24 @@ int scsi_device_get(struct scsi_device *sdev)
}
EXPORT_SYMBOL(scsi_device_get);
+/**
+ * scsi_device_put_nosleep - release a reference to a scsi_device
+ * @sdev: device to release a reference on.
+ *
+ * Description: Release a reference to the scsi_device and decrements the use
+ * count of the underlying LLDD module. This function may only be called from
+ * a call context where it is certain that the reference dropped is not the
+ * last one.
+ */
+void scsi_device_put_nosleep(struct scsi_device *sdev)
+{
+ struct module *mod = sdev->host->hostt->module;
+
+ put_device(&sdev->sdev_gendev);
+ module_put(mod);
+}
+EXPORT_SYMBOL(scsi_device_put);
+
/**
* scsi_device_put - release a reference to a scsi_device
* @sdev: device to release a reference on.
@@ -586,12 +604,9 @@ EXPORT_SYMBOL(scsi_device_get);
*/
void scsi_device_put(struct scsi_device *sdev)
{
- struct module *mod = sdev->host->hostt->module;
-
might_sleep();
- put_device(&sdev->sdev_gendev);
- module_put(mod);
+ scsi_device_put_nosleep(sdev);
}
EXPORT_SYMBOL(scsi_device_put);
@@ -365,6 +365,7 @@ void scsi_attach_vpd(struct scsi_device *sdev);
extern struct scsi_device *scsi_device_from_queue(struct request_queue *q);
extern int __must_check scsi_device_get(struct scsi_device *);
+extern void scsi_device_put_nosleep(struct scsi_device *);
extern void scsi_device_put(struct scsi_device *);
extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,
uint, uint, u64);