]> git.baikalelectronics.ru Git - kernel.git/commitdiff
scsi: core: Cache VPD pages b0, b1, b2
authorMartin K. Petersen <martin.petersen@oracle.com>
Wed, 2 Mar 2022 05:35:50 +0000 (00:35 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 2 May 2022 20:59:11 +0000 (16:59 -0400)
The SCSI disk driver consults VPD pages b0 (Block Limits), b1 (Block Device
Characteristics), and b2 (Logical Block Provisioning). Instead of having
sd.c request these pages every revalidate cycle, cache them along with the
other commonly used VPDs.

Link: https://lore.kernel.org/r/20220302053559.32147-6-martin.petersen@oracle.com
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi.c
drivers/scsi/scsi_sysfs.c
include/scsi/scsi_device.h

index 3db2a928faecfd93c4987dceb3bd2c02f3961e1d..c59eac7a32f2a087f0491b9d594a9e00f7950d47 100644 (file)
@@ -483,6 +483,12 @@ void scsi_attach_vpd(struct scsi_device *sdev)
                        scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83);
                if (vpd_buf->data[i] == 0x89)
                        scsi_update_vpd_page(sdev, 0x89, &sdev->vpd_pg89);
+               if (vpd_buf->data[i] == 0xb0)
+                       scsi_update_vpd_page(sdev, 0xb0, &sdev->vpd_pgb0);
+               if (vpd_buf->data[i] == 0xb1)
+                       scsi_update_vpd_page(sdev, 0xb1, &sdev->vpd_pgb1);
+               if (vpd_buf->data[i] == 0xb2)
+                       scsi_update_vpd_page(sdev, 0xb2, &sdev->vpd_pgb2);
        }
        kfree(vpd_buf);
 }
index dc6872e352bd4ea09b5cf7c9c945c2631c1af355..546a9e3cfbec450fef6e5cadcf3897021f954052 100644 (file)
@@ -448,6 +448,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
        struct list_head *this, *tmp;
        struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL;
        struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL;
+       struct scsi_vpd *vpd_pgb0 = NULL, *vpd_pgb1 = NULL, *vpd_pgb2 = NULL;
        unsigned long flags;
        struct module *mod;
 
@@ -490,6 +491,12 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
                                       lockdep_is_held(&sdev->inquiry_mutex));
        vpd_pg89 = rcu_replace_pointer(sdev->vpd_pg89, vpd_pg89,
                                       lockdep_is_held(&sdev->inquiry_mutex));
+       vpd_pgb0 = rcu_replace_pointer(sdev->vpd_pgb0, vpd_pgb0,
+                                      lockdep_is_held(&sdev->inquiry_mutex));
+       vpd_pgb1 = rcu_replace_pointer(sdev->vpd_pgb1, vpd_pgb1,
+                                      lockdep_is_held(&sdev->inquiry_mutex));
+       vpd_pgb2 = rcu_replace_pointer(sdev->vpd_pgb2, vpd_pgb2,
+                                      lockdep_is_held(&sdev->inquiry_mutex));
        mutex_unlock(&sdev->inquiry_mutex);
 
        if (vpd_pg0)
@@ -500,6 +507,12 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
                kfree_rcu(vpd_pg80, rcu);
        if (vpd_pg89)
                kfree_rcu(vpd_pg89, rcu);
+       if (vpd_pgb0)
+               kfree_rcu(vpd_pgb0, rcu);
+       if (vpd_pgb1)
+               kfree_rcu(vpd_pgb1, rcu);
+       if (vpd_pgb2)
+               kfree_rcu(vpd_pgb2, rcu);
        kfree(sdev->inquiry);
        kfree(sdev);
 
@@ -913,6 +926,9 @@ static struct bin_attribute dev_attr_vpd_##_page = {                \
 sdev_vpd_pg_attr(pg83);
 sdev_vpd_pg_attr(pg80);
 sdev_vpd_pg_attr(pg89);
+sdev_vpd_pg_attr(pgb0);
+sdev_vpd_pg_attr(pgb1);
+sdev_vpd_pg_attr(pgb2);
 sdev_vpd_pg_attr(pg0);
 
 static ssize_t show_inquiry(struct file *filep, struct kobject *kobj,
@@ -1250,6 +1266,15 @@ static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj,
        if (attr == &dev_attr_vpd_pg89 && !sdev->vpd_pg89)
                return 0;
 
+       if (attr == &dev_attr_vpd_pgb0 && !sdev->vpd_pgb0)
+               return 0;
+
+       if (attr == &dev_attr_vpd_pgb1 && !sdev->vpd_pgb1)
+               return 0;
+
+       if (attr == &dev_attr_vpd_pgb2 && !sdev->vpd_pgb2)
+               return 0;
+
        return S_IRUGO;
 }
 
@@ -1296,6 +1321,9 @@ static struct bin_attribute *scsi_sdev_bin_attrs[] = {
        &dev_attr_vpd_pg83,
        &dev_attr_vpd_pg80,
        &dev_attr_vpd_pg89,
+       &dev_attr_vpd_pgb0,
+       &dev_attr_vpd_pgb1,
+       &dev_attr_vpd_pgb2,
        &dev_attr_inquiry,
        NULL
 };
index c37cc5b3ebebb67f7a2d7a2f38580498264e3f33..7cf5f3b7589f57fb9ff42e058f96dc911da54126 100644 (file)
@@ -149,6 +149,10 @@ struct scsi_device {
        struct scsi_vpd __rcu *vpd_pg83;
        struct scsi_vpd __rcu *vpd_pg80;
        struct scsi_vpd __rcu *vpd_pg89;
+       struct scsi_vpd __rcu *vpd_pgb0;
+       struct scsi_vpd __rcu *vpd_pgb1;
+       struct scsi_vpd __rcu *vpd_pgb2;
+
        struct scsi_target      *sdev_target;
 
        blist_flags_t           sdev_bflags; /* black/white flags as also found in