-
Notifications
You must be signed in to change notification settings - Fork 0
/
hpsa-fixup-device-updating-code-for-phys-disk-array
118 lines (106 loc) · 4.21 KB
/
hpsa-fixup-device-updating-code-for-phys-disk-array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
hpsa: fix code that updates h->dev[]->phys_disk[]
From: Stephen M. Cameron <scameron@beardog.cce.hp.com>
h->dev[]->phys_disk[] contains a map of the physical
disks that make up each logical drive. When a RAID
migration occurs, this map can change for a logical
drive. We need to make sure it gets updated in a
consistent way and that this mapping is not used until
after it is finished being updated.
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
drivers/scsi/hpsa.c | 26 +++++++++++++++++++++++---
drivers/scsi/hpsa.h | 1 +
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 4a388e2..deaf662 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1161,6 +1161,8 @@ lun_assigned:
h->dev[n] = device;
h->ndevices++;
+ device->offload_to_be_enabled = device->offload_enabled;
+ device->offload_enabled = 0;
added[*nadded] = device;
(*nadded)++;
@@ -1200,11 +1202,17 @@ static void hpsa_scsi_update_entry(struct ctlr_info *h, int hostno,
*/
h->dev[entry]->raid_map = new_entry->raid_map;
h->dev[entry]->ioaccel_handle = new_entry->ioaccel_handle;
- wmb(); /* ensure raid map updated prior to ->offload_enabled */
}
h->dev[entry]->offload_config = new_entry->offload_config;
h->dev[entry]->offload_to_mirror = new_entry->offload_to_mirror;
- h->dev[entry]->offload_enabled = new_entry->offload_enabled;
+
+ /* We can turn off ioaccel offload now, but need to delay turning
+ * it on until we can update h->dev[entry]->phys_disk[], but we
+ * can't do that until all the devices are updated.
+ */
+ h->dev[entry]->offload_to_be_enabled = new_entry->offload_enabled;
+ if (!new_entry->offload_enabled)
+ h->dev[entry]->offload_enabled = 0;
dev_info(&h->pdev->dev,
"updated scsi %d:%d:%d:%d: %s %.8s %.16s RAID-%s SSDSmartPathCap%c En%c Exp=%d\n",
@@ -1239,6 +1247,8 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
new_entry->lun = h->dev[entry]->lun;
}
+ new_entry->offload_to_be_enabled = new_entry->offload_enabled;
+ new_entry->offload_enabled = 0;
h->dev[entry] = new_entry;
added[*nadded] = new_entry;
(*nadded)++;
@@ -1659,6 +1669,14 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
/* but if it does happen, we just ignore that device */
}
}
+ hpsa_update_log_drive_phys_drive_ptrs(h, h->dev, h->ndevices);
+
+ /* Now that h->dev[]->phys_disk[] is coherent, we can enable
+ * any logical drives that need it enabled.
+ */
+ for (i = 0; i < h->ndevices; i++)
+ h->dev[i]->offload_enabled = h->dev[i]->offload_to_be_enabled;
+
spin_unlock_irqrestore(&h->devlock, flags);
/* Monitor devices which are in one of several NOT READY states to be
@@ -2773,6 +2791,7 @@ static void hpsa_get_ioaccel_status(struct ctlr_info *h,
this_device->offload_config = 0;
this_device->offload_enabled = 0;
+ this_device->offload_to_be_enabled = 0;
buf = kzalloc(64, GFP_KERNEL);
if (!buf)
@@ -2796,6 +2815,7 @@ static void hpsa_get_ioaccel_status(struct ctlr_info *h,
if (hpsa_get_raid_map(h, scsi3addr, this_device))
this_device->offload_enabled = 0;
}
+ this_device->offload_to_be_enabled = this_device->offload_enabled;
out:
kfree(buf);
return;
@@ -3100,6 +3120,7 @@ static int hpsa_update_device_info(struct ctlr_info *h,
this_device->raid_level = RAID_UNKNOWN;
this_device->offload_config = 0;
this_device->offload_enabled = 0;
+ this_device->offload_to_be_enabled = 0;
this_device->volume_offline = 0;
}
@@ -3588,7 +3609,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
if (ncurrent >= HPSA_MAX_DEVICES)
break;
}
- hpsa_update_log_drive_phys_drive_ptrs(h, currentsd, ncurrent);
adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent);
out:
kfree(tmpdevice);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index cff0aaf..4feb728 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -54,6 +54,7 @@ struct hpsa_scsi_dev_t {
u32 ioaccel_handle;
int offload_config; /* I/O accel RAID offload configured */
int offload_enabled; /* I/O accel RAID offload enabled */
+ int offload_to_be_enabled;
int offload_to_mirror; /* Send next I/O accelerator RAID
* offload request to mirror drive
*/