Skip to content

Commit a1a825a

Browse files
igawkeithbusch
authored andcommitted
nvme: add csi, ms and nuse to sysfs
libnvme is using the sysfs for enumarating the nvme resources. Though there are few missing attritbutes in the sysfs. For these libnvme issues commands during discovering. As the kernel already knows all these attributes and we would like to avoid libnvme to issue commands all the time, expose these missing attributes. The nuse value is updated on request because the nuse is a volatile value. Since any user can read the sysfs attribute, a very simple rate limit is added (update once every 5 seconds). A more sophisticated update strategy can be added later if there is actually a need for it. Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: Daniel Wagner <[email protected]> Signed-off-by: Keith Busch <[email protected]>
1 parent 83ac678 commit a1a825a

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

drivers/nvme/host/core.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/ptrace.h>
2121
#include <linux/nvme_ioctl.h>
2222
#include <linux/pm_qos.h>
23+
#include <linux/ratelimit.h>
2324
#include <asm/unaligned.h>
2425

2526
#include "nvme.h"
@@ -1449,7 +1450,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl,
14491450
return status;
14501451
}
14511452

1452-
static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
1453+
int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
14531454
struct nvme_id_ns **id)
14541455
{
14551456
struct nvme_command c = { };
@@ -2040,6 +2041,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
20402041
blk_mq_freeze_queue(ns->disk->queue);
20412042
lbaf = nvme_lbaf_index(id->flbas);
20422043
ns->head->lba_shift = id->lbaf[lbaf].ds;
2044+
ns->head->nuse = le64_to_cpu(id->nuse);
20432045
nvme_set_queue_limits(ns->ctrl, ns->queue);
20442046

20452047
ret = nvme_configure_metadata(ns->ctrl, ns->head, id);
@@ -3420,6 +3422,8 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
34203422
head->ns_id = info->nsid;
34213423
head->ids = info->ids;
34223424
head->shared = info->is_shared;
3425+
ratelimit_state_init(&head->rs_nuse, 5 * HZ, 1);
3426+
ratelimit_set_flags(&head->rs_nuse, RATELIMIT_MSG_ON_RELEASE);
34233427
kref_init(&head->ref);
34243428

34253429
if (head->ids.csi) {

drivers/nvme/host/nvme.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/rcupdate.h>
1717
#include <linux/wait.h>
1818
#include <linux/t10-pi.h>
19+
#include <linux/ratelimit_types.h>
1920

2021
#include <trace/events/block.h>
2122

@@ -451,13 +452,16 @@ struct nvme_ns_head {
451452
u16 pi_size;
452453
u16 sgs;
453454
u32 sws;
455+
u64 nuse;
454456
u8 pi_type;
455457
u8 guard_type;
456458
#ifdef CONFIG_BLK_DEV_ZONED
457459
u64 zsze;
458460
#endif
459461
unsigned long features;
460462

463+
struct ratelimit_state rs_nuse;
464+
461465
struct cdev cdev;
462466
struct device cdev_device;
463467

@@ -862,6 +866,8 @@ int nvme_ns_chr_uring_cmd(struct io_uring_cmd *ioucmd,
862866
unsigned int issue_flags);
863867
int nvme_ns_head_chr_uring_cmd(struct io_uring_cmd *ioucmd,
864868
unsigned int issue_flags);
869+
int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
870+
struct nvme_id_ns **id);
865871
int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo);
866872
int nvme_dev_uring_cmd(struct io_uring_cmd *ioucmd, unsigned int issue_flags);
867873

drivers/nvme/host/sysfs.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,97 @@ static ssize_t nsid_show(struct device *dev, struct device_attribute *attr,
114114
}
115115
static DEVICE_ATTR_RO(nsid);
116116

117+
static ssize_t csi_show(struct device *dev, struct device_attribute *attr,
118+
char *buf)
119+
{
120+
return sysfs_emit(buf, "%u\n", dev_to_ns_head(dev)->ids.csi);
121+
}
122+
static DEVICE_ATTR_RO(csi);
123+
124+
static ssize_t metadata_bytes_show(struct device *dev,
125+
struct device_attribute *attr, char *buf)
126+
{
127+
return sysfs_emit(buf, "%u\n", dev_to_ns_head(dev)->ms);
128+
}
129+
static DEVICE_ATTR_RO(metadata_bytes);
130+
131+
static int ns_head_update_nuse(struct nvme_ns_head *head)
132+
{
133+
struct nvme_id_ns *id;
134+
struct nvme_ns *ns;
135+
int srcu_idx, ret = -EWOULDBLOCK;
136+
137+
/* Avoid issuing commands too often by rate limiting the update */
138+
if (!__ratelimit(&head->rs_nuse))
139+
return 0;
140+
141+
srcu_idx = srcu_read_lock(&head->srcu);
142+
ns = nvme_find_path(head);
143+
if (!ns)
144+
goto out_unlock;
145+
146+
ret = nvme_identify_ns(ns->ctrl, head->ns_id, &id);
147+
if (ret)
148+
goto out_unlock;
149+
150+
head->nuse = le64_to_cpu(id->nuse);
151+
kfree(id);
152+
153+
out_unlock:
154+
srcu_read_unlock(&head->srcu, srcu_idx);
155+
return ret;
156+
}
157+
158+
static int ns_update_nuse(struct nvme_ns *ns)
159+
{
160+
struct nvme_id_ns *id;
161+
int ret;
162+
163+
/* Avoid issuing commands too often by rate limiting the update. */
164+
if (!__ratelimit(&ns->head->rs_nuse))
165+
return 0;
166+
167+
ret = nvme_identify_ns(ns->ctrl, ns->head->ns_id, &id);
168+
if (ret)
169+
goto out_free_id;
170+
171+
ns->head->nuse = le64_to_cpu(id->nuse);
172+
173+
out_free_id:
174+
kfree(id);
175+
176+
return ret;
177+
}
178+
179+
static ssize_t nuse_show(struct device *dev, struct device_attribute *attr,
180+
char *buf)
181+
{
182+
struct nvme_ns_head *head = dev_to_ns_head(dev);
183+
struct gendisk *disk = dev_to_disk(dev);
184+
struct block_device *bdev = disk->part0;
185+
int ret;
186+
187+
if (IS_ENABLED(CONFIG_NVME_MULTIPATH) &&
188+
bdev->bd_disk->fops == &nvme_ns_head_ops)
189+
ret = ns_head_update_nuse(head);
190+
else
191+
ret = ns_update_nuse(bdev->bd_disk->private_data);
192+
if (ret)
193+
return ret;
194+
195+
return sysfs_emit(buf, "%llu\n", head->nuse);
196+
}
197+
static DEVICE_ATTR_RO(nuse);
198+
117199
static struct attribute *nvme_ns_attrs[] = {
118200
&dev_attr_wwid.attr,
119201
&dev_attr_uuid.attr,
120202
&dev_attr_nguid.attr,
121203
&dev_attr_eui.attr,
204+
&dev_attr_csi.attr,
122205
&dev_attr_nsid.attr,
206+
&dev_attr_metadata_bytes.attr,
207+
&dev_attr_nuse.attr,
123208
#ifdef CONFIG_NVME_MULTIPATH
124209
&dev_attr_ana_grpid.attr,
125210
&dev_attr_ana_state.attr,

0 commit comments

Comments
 (0)