[Hyper-V] Crash in hot-add/remove scsi devices (smp)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Fix Released
|
Medium
|
Unassigned | ||
Trusty |
Fix Released
|
Medium
|
Unassigned | ||
Vivid |
Fix Released
|
Medium
|
Unassigned | ||
Wily |
Fix Released
|
Medium
|
Unassigned | ||
Xenial |
Fix Released
|
Medium
|
Unassigned |
Bug Description
On some host errors storvsc module tries to remove sdev by scheduling a job
which does the following:
sdev = scsi_device_
if (sdev) {
}
While this code seems correct the following crash is observed:
general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC
RIP: 0010:[<
...
[<ffffffff814a
[<ffffffff8127
[<ffffffffa00b
[<ffffffffa00b
[<ffffffffa00e
[<ffffffff8108
...
The problem comes with the fact that many such jobs (for the same device)
are being scheduled simultaneously. While scsi_remove_
shost->scan_mutex and scsi_device_
SDEV_DEL state there is no protection against someone who did
scsi_device_
the whole scenario looks like that: two callers do simultaneous (or
preemption happens) calls to scsi_device_
for all of them, after that both callers try doing scsi_remove_
shost->scan_mutex only serializes their calls to __scsi_
and we end up doing the cleanup path twice.
Signed-off-by: Vitaly Kuznetsov <email address hidden>
---
drivers/
1 file changed, 8 insertions(+)
diff --git a/drivers/
index b333389..e0d2707 100644
--- a/drivers/
+++ b/drivers/
@@ -1076,6 +1076,14 @@ void __scsi_
{
struct device *dev = &sdev->sdev_gendev;
+ /*
+ * This cleanup path is not reentrant and while it is impossible
+ * to get a new reference with scsi_device_get() someone can still
+ * hold a previously acquired one.
+ */
+ if (sdev->sdev_state == SDEV_DEL)
+ return;
+
if (sdev->is_visible) {
if (scsi_device_
--
2.4.3
tags: | added: kernel-da-key kernel-hyper-v |
Changed in linux (Ubuntu): | |
status: | New → Confirmed |
Changed in linux (Ubuntu): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Vivid): | |
status: | New → In Progress |
Changed in linux (Ubuntu Trusty): | |
status: | New → In Progress |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Vivid): | |
importance: | Undecided → Medium |
assignee: | nobody → Joseph Salisbury (jsalisbury) |
Changed in linux (Ubuntu Trusty): | |
assignee: | nobody → Joseph Salisbury (jsalisbury) |
Changed in linux (Ubuntu Trusty): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Vivid): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Wily): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Xenial): | |
status: | In Progress → Fix Committed |
tags: |
added: verification-done-vivid removed: verification-needed-vivid |
tags: |
added: verification-done-wily removed: verification-needed-wily |
I don't see this patch in mainline as of yet. Is it in any upstream repos? Do you want me to build a test kernel with this patch?