Only annotate pointers that are shared across threads with __rcu.
Use rcu_dereference() when dereferencing an RCU pointer. Protect
also the RCU pointer dereferences when freeing RCU pointers. This
patch suppresses about twenty sparse complaints about the vpd_pg8[03]
pointers.

Fixes: commit 09e2b0b14690 ("scsi: rescan VPD attributes")
Signed-off-by: Bart Van Assche <bart.vanass...@wdc.com>
Cc: Christoph Hellwig <h...@lst.de>
Cc: Hannes Reinecke <h...@suse.de>
Cc: Johannes Thumshirn <jthumsh...@suse.de>
Cc: Shane Seymour <shane.seym...@hpe.com>
---
 drivers/scsi/scsi.c       | 6 +++---
 drivers/scsi/scsi_lib.c   | 8 ++++----
 drivers/scsi/scsi_sysfs.c | 7 +++++--
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 3d38c6d463b8..5bb15e698969 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -426,7 +426,7 @@ void scsi_attach_vpd(struct scsi_device *sdev)
        int vpd_len = SCSI_VPD_PG_LEN;
        int pg80_supported = 0;
        int pg83_supported = 0;
-       unsigned char __rcu *vpd_buf, *orig_vpd_buf = NULL;
+       unsigned char *vpd_buf, *orig_vpd_buf = NULL;
 
        if (!scsi_device_supports_vpd(sdev))
                return;
@@ -474,7 +474,7 @@ void scsi_attach_vpd(struct scsi_device *sdev)
                        goto retry_pg80;
                }
                mutex_lock(&sdev->inquiry_mutex);
-               orig_vpd_buf = sdev->vpd_pg80;
+               orig_vpd_buf = rcu_dereference(sdev->vpd_pg80);
                sdev->vpd_pg80_len = result;
                rcu_assign_pointer(sdev->vpd_pg80, vpd_buf);
                mutex_unlock(&sdev->inquiry_mutex);
@@ -503,7 +503,7 @@ void scsi_attach_vpd(struct scsi_device *sdev)
                        goto retry_pg83;
                }
                mutex_lock(&sdev->inquiry_mutex);
-               orig_vpd_buf = sdev->vpd_pg83;
+               orig_vpd_buf = rcu_dereference(sdev->vpd_pg83);
                sdev->vpd_pg83_len = result;
                rcu_assign_pointer(sdev->vpd_pg83, vpd_buf);
                mutex_unlock(&sdev->inquiry_mutex);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 1905962fb992..2ca91d251c5f 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -3282,7 +3282,7 @@ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, 
size_t id_len)
        u8 cur_id_type = 0xff;
        u8 cur_id_size = 0;
        unsigned char *d, *cur_id_str;
-       unsigned char __rcu *vpd_pg83;
+       unsigned char *vpd_pg83;
        int id_size = -EINVAL;
 
        rcu_read_lock();
@@ -3431,7 +3431,7 @@ EXPORT_SYMBOL(scsi_vpd_lun_id);
 int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id)
 {
        unsigned char *d;
-       unsigned char __rcu *vpd_pg83;
+       unsigned char *vpd_pg83;
        int group_id = -EAGAIN, rel_port = -1;
 
        rcu_read_lock();
@@ -3441,8 +3441,8 @@ int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id)
                return -ENXIO;
        }
 
-       d = sdev->vpd_pg83 + 4;
-       while (d < sdev->vpd_pg83 + sdev->vpd_pg83_len) {
+       d = vpd_pg83 + 4;
+       while (d < vpd_pg83 + sdev->vpd_pg83_len) {
                switch (d[1] & 0xf) {
                case 0x4:
                        /* Relative target port */
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 5ed473a87589..cf8a2088a9ba 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -456,8 +456,11 @@ static void scsi_device_dev_release_usercontext(struct 
work_struct *work)
        /* NULL queue means the device can't be used */
        sdev->request_queue = NULL;
 
-       kfree(sdev->vpd_pg83);
-       kfree(sdev->vpd_pg80);
+       mutex_lock(&sdev->inquiry_mutex);
+       kfree(rcu_dereference(sdev->vpd_pg83));
+       kfree(rcu_dereference(sdev->vpd_pg80));
+       mutex_unlock(&sdev->inquiry_mutex);
+
        kfree(sdev->inquiry);
        kfree(sdev);
 
-- 
2.14.0

Reply via email to