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

scsi: Rework handling of scsi_device.vpd_pg8[03]

Introduce struct scsi_vpd for the VPD page length, data and the RCU head
that will be used to free the VPD data. Use kfree_rcu() instead of
kfree() to free VPD data. Move the VPD buffer pointer check inside the
RCU read lock in the sysfs code. Only annotate pointers that are shared
across threads with __rcu. Use rcu_dereference() when dereferencing an
RCU pointer. This patch suppresses about twenty sparse complaints about
the vpd_pg8[03] pointers. This patch also fixes a race condition, namely
that updating of the VPD pointers and length variables in struct
scsi_device was not atomic with reference to the code reading these
variables. See also "Does the update code tolerate concurrent accesses?"
in Documentation/RCU/checklist.txt.

Fixes: commit 09e2b0b14690 ("scsi: rescan VPD attributes")
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Acked-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Shane Seymour <shane.seymour@hpe.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Johannes Thumshirn <jthumshirn@suse.de>
Cc: Shane Seymour <shane.seymour@hpe.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Bart Van Assche and committed by
Martin K. Petersen
ccf1e004 1e3f720a

+60 -47
+18 -26
drivers/scsi/scsi.c
··· 415 * scsi_get_vpd_buf - Get Vital Product Data from a SCSI device 416 * @sdev: The device to ask 417 * @page: Which Vital Product Data to return 418 - * @len: Upon success, the VPD length will be stored in *@len. 419 * 420 * Returns %NULL upon failure. 421 */ 422 - static unsigned char *scsi_get_vpd_buf(struct scsi_device *sdev, u8 page, 423 - int *len) 424 { 425 - unsigned char *vpd_buf; 426 int vpd_len = SCSI_VPD_PG_LEN, result; 427 428 retry_pg: 429 - vpd_buf = kmalloc(vpd_len, GFP_KERNEL); 430 if (!vpd_buf) 431 return NULL; 432 433 - result = scsi_vpd_inquiry(sdev, vpd_buf, page, vpd_len); 434 if (result < 0) { 435 kfree(vpd_buf); 436 return NULL; ··· 439 goto retry_pg; 440 } 441 442 - *len = result; 443 444 return vpd_buf; 445 } 446 447 static void scsi_update_vpd_page(struct scsi_device *sdev, u8 page, 448 - unsigned char __rcu **sdev_vpd_buf, 449 - int *sdev_vpd_len) 450 { 451 - unsigned char *vpd_buf; 452 - int len; 453 454 - vpd_buf = scsi_get_vpd_buf(sdev, page, &len); 455 if (!vpd_buf) 456 return; 457 458 mutex_lock(&sdev->inquiry_mutex); 459 rcu_swap_protected(*sdev_vpd_buf, vpd_buf, 460 lockdep_is_held(&sdev->inquiry_mutex)); 461 - *sdev_vpd_len = len; 462 mutex_unlock(&sdev->inquiry_mutex); 463 464 - synchronize_rcu(); 465 - 466 - kfree(vpd_buf); 467 } 468 469 /** ··· 473 */ 474 void scsi_attach_vpd(struct scsi_device *sdev) 475 { 476 - int i, vpd_len; 477 - unsigned char *vpd_buf; 478 479 if (!scsi_device_supports_vpd(sdev)) 480 return; 481 482 /* Ask for all the pages supported by this device */ 483 - vpd_buf = scsi_get_vpd_buf(sdev, 0, &vpd_len); 484 if (!vpd_buf) 485 return; 486 487 - for (i = 4; i < vpd_len; i++) { 488 - if (vpd_buf[i] == 0x80) 489 - scsi_update_vpd_page(sdev, 0x80, &sdev->vpd_pg80, 490 - &sdev->vpd_pg80_len); 491 - if (vpd_buf[i] == 0x83) 492 - scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83, 493 - &sdev->vpd_pg83_len); 494 } 495 kfree(vpd_buf); 496 }
··· 415 * scsi_get_vpd_buf - Get Vital Product Data from a SCSI device 416 * @sdev: The device to ask 417 * @page: Which Vital Product Data to return 418 * 419 * Returns %NULL upon failure. 420 */ 421 + static struct scsi_vpd *scsi_get_vpd_buf(struct scsi_device *sdev, u8 page) 422 { 423 + struct scsi_vpd *vpd_buf; 424 int vpd_len = SCSI_VPD_PG_LEN, result; 425 426 retry_pg: 427 + vpd_buf = kmalloc(sizeof(*vpd_buf) + vpd_len, GFP_KERNEL); 428 if (!vpd_buf) 429 return NULL; 430 431 + result = scsi_vpd_inquiry(sdev, vpd_buf->data, page, vpd_len); 432 if (result < 0) { 433 kfree(vpd_buf); 434 return NULL; ··· 441 goto retry_pg; 442 } 443 444 + vpd_buf->len = result; 445 446 return vpd_buf; 447 } 448 449 static void scsi_update_vpd_page(struct scsi_device *sdev, u8 page, 450 + struct scsi_vpd __rcu **sdev_vpd_buf) 451 { 452 + struct scsi_vpd *vpd_buf; 453 454 + vpd_buf = scsi_get_vpd_buf(sdev, page); 455 if (!vpd_buf) 456 return; 457 458 mutex_lock(&sdev->inquiry_mutex); 459 rcu_swap_protected(*sdev_vpd_buf, vpd_buf, 460 lockdep_is_held(&sdev->inquiry_mutex)); 461 mutex_unlock(&sdev->inquiry_mutex); 462 463 + if (vpd_buf) 464 + kfree_rcu(vpd_buf, rcu); 465 } 466 467 /** ··· 479 */ 480 void scsi_attach_vpd(struct scsi_device *sdev) 481 { 482 + int i; 483 + struct scsi_vpd *vpd_buf; 484 485 if (!scsi_device_supports_vpd(sdev)) 486 return; 487 488 /* Ask for all the pages supported by this device */ 489 + vpd_buf = scsi_get_vpd_buf(sdev, 0); 490 if (!vpd_buf) 491 return; 492 493 + for (i = 4; i < vpd_buf->len; i++) { 494 + if (vpd_buf->data[i] == 0x80) 495 + scsi_update_vpd_page(sdev, 0x80, &sdev->vpd_pg80); 496 + if (vpd_buf->data[i] == 0x83) 497 + scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83); 498 } 499 kfree(vpd_buf); 500 }
+8 -8
drivers/scsi/scsi_lib.c
··· 3272 { 3273 u8 cur_id_type = 0xff; 3274 u8 cur_id_size = 0; 3275 - unsigned char *d, *cur_id_str; 3276 - unsigned char __rcu *vpd_pg83; 3277 int id_size = -EINVAL; 3278 3279 rcu_read_lock(); ··· 3304 } 3305 3306 memset(id, 0, id_len); 3307 - d = vpd_pg83 + 4; 3308 - while (d < vpd_pg83 + sdev->vpd_pg83_len) { 3309 /* Skip designators not referring to the LUN */ 3310 if ((d[1] & 0x30) != 0x00) 3311 goto next_desig; ··· 3421 */ 3422 int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id) 3423 { 3424 - unsigned char *d; 3425 - unsigned char __rcu *vpd_pg83; 3426 int group_id = -EAGAIN, rel_port = -1; 3427 3428 rcu_read_lock(); ··· 3432 return -ENXIO; 3433 } 3434 3435 - d = sdev->vpd_pg83 + 4; 3436 - while (d < sdev->vpd_pg83 + sdev->vpd_pg83_len) { 3437 switch (d[1] & 0xf) { 3438 case 0x4: 3439 /* Relative target port */
··· 3272 { 3273 u8 cur_id_type = 0xff; 3274 u8 cur_id_size = 0; 3275 + const unsigned char *d, *cur_id_str; 3276 + const struct scsi_vpd *vpd_pg83; 3277 int id_size = -EINVAL; 3278 3279 rcu_read_lock(); ··· 3304 } 3305 3306 memset(id, 0, id_len); 3307 + d = vpd_pg83->data + 4; 3308 + while (d < vpd_pg83->data + vpd_pg83->len) { 3309 /* Skip designators not referring to the LUN */ 3310 if ((d[1] & 0x30) != 0x00) 3311 goto next_desig; ··· 3421 */ 3422 int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id) 3423 { 3424 + const unsigned char *d; 3425 + const struct scsi_vpd *vpd_pg83; 3426 int group_id = -EAGAIN, rel_port = -1; 3427 3428 rcu_read_lock(); ··· 3432 return -ENXIO; 3433 } 3434 3435 + d = vpd_pg83->data + 4; 3436 + while (d < vpd_pg83->data + vpd_pg83->len) { 3437 switch (d[1] & 0xf) { 3438 case 0x4: 3439 /* Relative target port */
+20 -9
drivers/scsi/scsi_sysfs.c
··· 428 struct scsi_device *sdev; 429 struct device *parent; 430 struct list_head *this, *tmp; 431 unsigned long flags; 432 433 sdev = container_of(work, struct scsi_device, ew.work); ··· 457 /* NULL queue means the device can't be used */ 458 sdev->request_queue = NULL; 459 460 - kfree(sdev->vpd_pg83); 461 - kfree(sdev->vpd_pg80); 462 kfree(sdev->inquiry); 463 kfree(sdev); 464 ··· 805 { \ 806 struct device *dev = container_of(kobj, struct device, kobj); \ 807 struct scsi_device *sdev = to_scsi_device(dev); \ 808 - int ret; \ 809 - if (!sdev->vpd_##_page) \ 810 - return -EINVAL; \ 811 rcu_read_lock(); \ 812 - ret = memory_read_from_buffer(buf, count, &off, \ 813 - rcu_dereference(sdev->vpd_##_page), \ 814 - sdev->vpd_##_page##_len); \ 815 rcu_read_unlock(); \ 816 - return ret; \ 817 } \ 818 static struct bin_attribute dev_attr_vpd_##_page = { \ 819 .attr = {.name = __stringify(vpd_##_page), .mode = S_IRUGO }, \
··· 428 struct scsi_device *sdev; 429 struct device *parent; 430 struct list_head *this, *tmp; 431 + struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; 432 unsigned long flags; 433 434 sdev = container_of(work, struct scsi_device, ew.work); ··· 456 /* NULL queue means the device can't be used */ 457 sdev->request_queue = NULL; 458 459 + mutex_lock(&sdev->inquiry_mutex); 460 + rcu_swap_protected(sdev->vpd_pg80, vpd_pg80, 461 + lockdep_is_held(&sdev->inquiry_mutex)); 462 + rcu_swap_protected(sdev->vpd_pg83, vpd_pg83, 463 + lockdep_is_held(&sdev->inquiry_mutex)); 464 + mutex_unlock(&sdev->inquiry_mutex); 465 + 466 + if (vpd_pg83) 467 + kfree_rcu(vpd_pg83, rcu); 468 + if (vpd_pg80) 469 + kfree_rcu(vpd_pg80, rcu); 470 kfree(sdev->inquiry); 471 kfree(sdev); 472 ··· 795 { \ 796 struct device *dev = container_of(kobj, struct device, kobj); \ 797 struct scsi_device *sdev = to_scsi_device(dev); \ 798 + struct scsi_vpd *vpd_page; \ 799 + int ret = -EINVAL; \ 800 + \ 801 rcu_read_lock(); \ 802 + vpd_page = rcu_dereference(sdev->vpd_##_page); \ 803 + if (vpd_page) \ 804 + ret = memory_read_from_buffer(buf, count, &off, \ 805 + vpd_page->data, vpd_page->len); \ 806 rcu_read_unlock(); \ 807 + return ret; \ 808 } \ 809 static struct bin_attribute dev_attr_vpd_##_page = { \ 810 .attr = {.name = __stringify(vpd_##_page), .mode = S_IRUGO }, \
+14 -4
include/scsi/scsi_device.h
··· 80 */ 81 }; 82 83 struct scsi_device { 84 struct Scsi_Host *host; 85 struct request_queue *request_queue; ··· 134 const char * rev; /* ... "nullnullnullnull" before scan */ 135 136 #define SCSI_VPD_PG_LEN 255 137 - int vpd_pg83_len; 138 - unsigned char __rcu *vpd_pg83; 139 - int vpd_pg80_len; 140 - unsigned char __rcu *vpd_pg80; 141 unsigned char current_tag; /* current tag */ 142 struct scsi_target *sdev_target; /* used only for single_lun */ 143
··· 80 */ 81 }; 82 83 + /** 84 + * struct scsi_vpd - SCSI Vital Product Data 85 + * @rcu: For kfree_rcu(). 86 + * @len: Length in bytes of @data. 87 + * @data: VPD data as defined in various T10 SCSI standard documents. 88 + */ 89 + struct scsi_vpd { 90 + struct rcu_head rcu; 91 + int len; 92 + unsigned char data[]; 93 + }; 94 + 95 struct scsi_device { 96 struct Scsi_Host *host; 97 struct request_queue *request_queue; ··· 122 const char * rev; /* ... "nullnullnullnull" before scan */ 123 124 #define SCSI_VPD_PG_LEN 255 125 + struct scsi_vpd __rcu *vpd_pg83; 126 + struct scsi_vpd __rcu *vpd_pg80; 127 unsigned char current_tag; /* current tag */ 128 struct scsi_target *sdev_target; /* used only for single_lun */ 129