Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

[S390] dasd: revert LCU optimization

Remove the optimization that validate server is only called once per
LCU. If a device is set online we only know that we already know the
LCU. But if the pathgroup was lost in between we have to do a
validate server again to activate some features.
Since we have no indication when a pathgroup gets lost we have to do
a validate server every time a device is set online.

Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Stefan Haberland and committed by
Martin Schwidefsky
f9f8d02f e0a15d5b

+16 -89
+1 -63
drivers/s390/block/dasd_alias.c
··· 189 189 unsigned long flags; 190 190 struct alias_server *server, *newserver; 191 191 struct alias_lcu *lcu, *newlcu; 192 - int is_lcu_known; 193 192 struct dasd_uid uid; 194 193 195 194 private = (struct dasd_eckd_private *) device->private; 196 195 197 196 device->discipline->get_uid(device, &uid); 198 197 spin_lock_irqsave(&aliastree.lock, flags); 199 - is_lcu_known = 1; 200 198 server = _find_server(&uid); 201 199 if (!server) { 202 200 spin_unlock_irqrestore(&aliastree.lock, flags); ··· 206 208 if (!server) { 207 209 list_add(&newserver->server, &aliastree.serverlist); 208 210 server = newserver; 209 - is_lcu_known = 0; 210 211 } else { 211 212 /* someone was faster */ 212 213 _free_server(newserver); ··· 223 226 if (!lcu) { 224 227 list_add(&newlcu->lcu, &server->lculist); 225 228 lcu = newlcu; 226 - is_lcu_known = 0; 227 229 } else { 228 230 /* someone was faster */ 229 231 _free_lcu(newlcu); 230 232 } 231 - is_lcu_known = 0; 232 233 } 233 234 spin_lock(&lcu->lock); 234 235 list_add(&device->alias_list, &lcu->inactive_devices); ··· 234 239 spin_unlock(&lcu->lock); 235 240 spin_unlock_irqrestore(&aliastree.lock, flags); 236 241 237 - return is_lcu_known; 238 - } 239 - 240 - /* 241 - * The first device to be registered on an LCU will have to do 242 - * some additional setup steps to configure that LCU on the 243 - * storage server. All further devices should wait with their 244 - * initialization until the first device is done. 245 - * To synchronize this work, the first device will call 246 - * dasd_alias_lcu_setup_complete when it is done, and all 247 - * other devices will wait for it with dasd_alias_wait_for_lcu_setup. 248 - */ 249 - void dasd_alias_lcu_setup_complete(struct dasd_device *device) 250 - { 251 - unsigned long flags; 252 - struct alias_server *server; 253 - struct alias_lcu *lcu; 254 - struct dasd_uid uid; 255 - 256 - device->discipline->get_uid(device, &uid); 257 - lcu = NULL; 258 - spin_lock_irqsave(&aliastree.lock, flags); 259 - server = _find_server(&uid); 260 - if (server) 261 - lcu = _find_lcu(server, &uid); 262 - spin_unlock_irqrestore(&aliastree.lock, flags); 263 - if (!lcu) { 264 - DBF_EVENT_DEVID(DBF_ERR, device->cdev, 265 - "could not find lcu for %04x %02x", 266 - uid.ssid, uid.real_unit_addr); 267 - WARN_ON(1); 268 - return; 269 - } 270 - complete_all(&lcu->lcu_setup); 271 - } 272 - 273 - void dasd_alias_wait_for_lcu_setup(struct dasd_device *device) 274 - { 275 - unsigned long flags; 276 - struct alias_server *server; 277 - struct alias_lcu *lcu; 278 - struct dasd_uid uid; 279 - 280 - device->discipline->get_uid(device, &uid); 281 - lcu = NULL; 282 - spin_lock_irqsave(&aliastree.lock, flags); 283 - server = _find_server(&uid); 284 - if (server) 285 - lcu = _find_lcu(server, &uid); 286 - spin_unlock_irqrestore(&aliastree.lock, flags); 287 - if (!lcu) { 288 - DBF_EVENT_DEVID(DBF_ERR, device->cdev, 289 - "could not find lcu for %04x %02x", 290 - uid.ssid, uid.real_unit_addr); 291 - WARN_ON(1); 292 - return; 293 - } 294 - wait_for_completion(&lcu->lcu_setup); 242 + return 0; 295 243 } 296 244 297 245 /*
+15 -26
drivers/s390/block/dasd_eckd.c
··· 1534 1534 struct dasd_eckd_private *private; 1535 1535 int enable_pav; 1536 1536 1537 + private = (struct dasd_eckd_private *) device->private; 1538 + if (private->uid.type == UA_BASE_PAV_ALIAS || 1539 + private->uid.type == UA_HYPER_PAV_ALIAS) 1540 + return; 1537 1541 if (dasd_nopav || MACHINE_IS_VM) 1538 1542 enable_pav = 0; 1539 1543 else ··· 1546 1542 1547 1543 /* may be requested feature is not available on server, 1548 1544 * therefore just report error and go ahead */ 1549 - private = (struct dasd_eckd_private *) device->private; 1550 1545 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x " 1551 1546 "returned rc=%d", private->uid.ssid, rc); 1552 1547 } ··· 1591 1588 struct dasd_eckd_private *private; 1592 1589 struct dasd_block *block; 1593 1590 struct dasd_uid temp_uid; 1594 - int is_known, rc, i; 1591 + int rc, i; 1595 1592 int readonly; 1596 1593 unsigned long value; 1597 1594 ··· 1654 1651 block->base = device; 1655 1652 } 1656 1653 1657 - /* register lcu with alias handling, enable PAV if this is a new lcu */ 1658 - is_known = dasd_alias_make_device_known_to_lcu(device); 1659 - if (is_known < 0) { 1660 - rc = is_known; 1654 + /* register lcu with alias handling, enable PAV */ 1655 + rc = dasd_alias_make_device_known_to_lcu(device); 1656 + if (rc) 1661 1657 goto out_err2; 1662 - } 1663 - /* 1664 - * dasd_eckd_validate_server is done on the first device that 1665 - * is found for an LCU. All later other devices have to wait 1666 - * for it, so they will read the correct feature codes. 1667 - */ 1668 - if (!is_known) { 1669 - dasd_eckd_validate_server(device); 1670 - dasd_alias_lcu_setup_complete(device); 1671 - } else 1672 - dasd_alias_wait_for_lcu_setup(device); 1658 + 1659 + dasd_eckd_validate_server(device); 1673 1660 1674 1661 /* device may report different configuration data after LCU setup */ 1675 1662 rc = dasd_eckd_read_conf(device); ··· 4091 4098 { 4092 4099 struct dasd_eckd_private *private; 4093 4100 struct dasd_eckd_characteristics temp_rdc_data; 4094 - int is_known, rc; 4101 + int rc; 4095 4102 struct dasd_uid temp_uid; 4096 4103 unsigned long flags; 4097 4104 ··· 4114 4121 goto out_err; 4115 4122 4116 4123 /* register lcu with alias handling, enable PAV if this is a new lcu */ 4117 - is_known = dasd_alias_make_device_known_to_lcu(device); 4118 - if (is_known < 0) 4119 - return is_known; 4120 - if (!is_known) { 4121 - dasd_eckd_validate_server(device); 4122 - dasd_alias_lcu_setup_complete(device); 4123 - } else 4124 - dasd_alias_wait_for_lcu_setup(device); 4124 + rc = dasd_alias_make_device_known_to_lcu(device); 4125 + if (rc) 4126 + return rc; 4127 + dasd_eckd_validate_server(device); 4125 4128 4126 4129 /* RE-Read Configuration Data */ 4127 4130 rc = dasd_eckd_read_conf(device);