Commit e60ac0b9 authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

scsi: core: Cache VPD pages b0, b1, b2

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: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e17d6340
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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);
}
+28 −0
Original line number Diff line number Diff line
@@ -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
};
+4 −0
Original line number Diff line number Diff line
@@ -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