Skip to content

Commit 1d8613a

Browse files
Can Guomartinkpetersen
authored andcommitted
scsi: ufs: core: Introduce HBA performance monitor sysfs nodes
Add a new sysfs group which has nodes to monitor data/request transfer performance. This sysfs group has nodes showing total sectors/requests transferred, total busy time spent and max/min/avg/sum latencies. This group can be enhanced later to show more UFS driver layer performance statistics data during runtime. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Daejun Park <[email protected]> Acked-by: Bean Huo <[email protected]> Signed-off-by: Can Guo <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 39107e8 commit 1d8613a

File tree

4 files changed

+446
-0
lines changed

4 files changed

+446
-0
lines changed

Documentation/ABI/testing/sysfs-driver-ufs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,132 @@ Description: This entry shows the target state of an UFS UIC link
995995

996996
The file is read only.
997997

998+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/monitor_enable
999+
Date: January 2021
1000+
Contact: Can Guo <[email protected]>
1001+
Description: This file shows the status of performance monitor enablement
1002+
and it can be used to start/stop the monitor. When the monitor
1003+
is stopped, the performance data collected is also cleared.
1004+
1005+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/monitor_chunk_size
1006+
Date: January 2021
1007+
Contact: Can Guo <[email protected]>
1008+
Description: This file tells the monitor to focus on requests transferring
1009+
data of specific chunk size (in Bytes). 0 means any chunk size.
1010+
It can only be changed when monitor is disabled.
1011+
1012+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_total_sectors
1013+
Date: January 2021
1014+
Contact: Can Guo <[email protected]>
1015+
Description: This file shows how many sectors (in 512 Bytes) have been
1016+
sent from device to host after monitor gets started.
1017+
1018+
The file is read only.
1019+
1020+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_total_busy
1021+
Date: January 2021
1022+
Contact: Can Guo <[email protected]>
1023+
Description: This file shows how long (in micro seconds) has been spent
1024+
sending data from device to host after monitor gets started.
1025+
1026+
The file is read only.
1027+
1028+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_nr_requests
1029+
Date: January 2021
1030+
Contact: Can Guo <[email protected]>
1031+
Description: This file shows how many read requests have been sent after
1032+
monitor gets started.
1033+
1034+
The file is read only.
1035+
1036+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_max
1037+
Date: January 2021
1038+
Contact: Can Guo <[email protected]>
1039+
Description: This file shows the maximum latency (in micro seconds) of
1040+
read requests after monitor gets started.
1041+
1042+
The file is read only.
1043+
1044+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_min
1045+
Date: January 2021
1046+
Contact: Can Guo <[email protected]>
1047+
Description: This file shows the minimum latency (in micro seconds) of
1048+
read requests after monitor gets started.
1049+
1050+
The file is read only.
1051+
1052+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_avg
1053+
Date: January 2021
1054+
Contact: Can Guo <[email protected]>
1055+
Description: This file shows the average latency (in micro seconds) of
1056+
read requests after monitor gets started.
1057+
1058+
The file is read only.
1059+
1060+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_sum
1061+
Date: January 2021
1062+
Contact: Can Guo <[email protected]>
1063+
Description: This file shows the total latency (in micro seconds) of
1064+
read requests sent after monitor gets started.
1065+
1066+
The file is read only.
1067+
1068+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_total_sectors
1069+
Date: January 2021
1070+
Contact: Can Guo <[email protected]>
1071+
Description: This file shows how many sectors (in 512 Bytes) have been sent
1072+
from host to device after monitor gets started.
1073+
1074+
The file is read only.
1075+
1076+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_total_busy
1077+
Date: January 2021
1078+
Contact: Can Guo <[email protected]>
1079+
Description: This file shows how long (in micro seconds) has been spent
1080+
sending data from host to device after monitor gets started.
1081+
1082+
The file is read only.
1083+
1084+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_nr_requests
1085+
Date: January 2021
1086+
Contact: Can Guo <[email protected]>
1087+
Description: This file shows how many write requests have been sent after
1088+
monitor gets started.
1089+
1090+
The file is read only.
1091+
1092+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_max
1093+
Date: January 2021
1094+
Contact: Can Guo <[email protected]>
1095+
Description: This file shows the maximum latency (in micro seconds) of write
1096+
requests after monitor gets started.
1097+
1098+
The file is read only.
1099+
1100+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_min
1101+
Date: January 2021
1102+
Contact: Can Guo <[email protected]>
1103+
Description: This file shows the minimum latency (in micro seconds) of write
1104+
requests after monitor gets started.
1105+
1106+
The file is read only.
1107+
1108+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_avg
1109+
Date: January 2021
1110+
Contact: Can Guo <[email protected]>
1111+
Description: This file shows the average latency (in micro seconds) of write
1112+
requests after monitor gets started.
1113+
1114+
The file is read only.
1115+
1116+
What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_sum
1117+
Date: January 2021
1118+
Contact: Can Guo <[email protected]>
1119+
Description: This file shows the total latency (in micro seconds) of write
1120+
requests after monitor gets started.
1121+
1122+
The file is read only.
1123+
9981124
What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_presv_us_en
9991125
Date: June 2020
10001126
Contact: Asutosh Das <[email protected]>

drivers/scsi/ufs/ufs-sysfs.c

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,242 @@ static const struct attribute_group ufs_sysfs_default_group = {
278278
.attrs = ufs_sysfs_ufshcd_attrs,
279279
};
280280

281+
static ssize_t monitor_enable_show(struct device *dev,
282+
struct device_attribute *attr, char *buf)
283+
{
284+
struct ufs_hba *hba = dev_get_drvdata(dev);
285+
286+
return sysfs_emit(buf, "%d\n", hba->monitor.enabled);
287+
}
288+
289+
static ssize_t monitor_enable_store(struct device *dev,
290+
struct device_attribute *attr,
291+
const char *buf, size_t count)
292+
{
293+
struct ufs_hba *hba = dev_get_drvdata(dev);
294+
unsigned long value, flags;
295+
296+
if (kstrtoul(buf, 0, &value))
297+
return -EINVAL;
298+
299+
value = !!value;
300+
spin_lock_irqsave(hba->host->host_lock, flags);
301+
if (value == hba->monitor.enabled)
302+
goto out_unlock;
303+
304+
if (!value) {
305+
memset(&hba->monitor, 0, sizeof(hba->monitor));
306+
} else {
307+
hba->monitor.enabled = true;
308+
hba->monitor.enabled_ts = ktime_get();
309+
}
310+
311+
out_unlock:
312+
spin_unlock_irqrestore(hba->host->host_lock, flags);
313+
return count;
314+
}
315+
316+
static ssize_t monitor_chunk_size_show(struct device *dev,
317+
struct device_attribute *attr, char *buf)
318+
{
319+
struct ufs_hba *hba = dev_get_drvdata(dev);
320+
321+
return sysfs_emit(buf, "%lu\n", hba->monitor.chunk_size);
322+
}
323+
324+
static ssize_t monitor_chunk_size_store(struct device *dev,
325+
struct device_attribute *attr,
326+
const char *buf, size_t count)
327+
{
328+
struct ufs_hba *hba = dev_get_drvdata(dev);
329+
unsigned long value, flags;
330+
331+
if (kstrtoul(buf, 0, &value))
332+
return -EINVAL;
333+
334+
spin_lock_irqsave(hba->host->host_lock, flags);
335+
/* Only allow chunk size change when monitor is disabled */
336+
if (!hba->monitor.enabled)
337+
hba->monitor.chunk_size = value;
338+
spin_unlock_irqrestore(hba->host->host_lock, flags);
339+
return count;
340+
}
341+
342+
static ssize_t read_total_sectors_show(struct device *dev,
343+
struct device_attribute *attr, char *buf)
344+
{
345+
struct ufs_hba *hba = dev_get_drvdata(dev);
346+
347+
return sysfs_emit(buf, "%lu\n", hba->monitor.nr_sec_rw[READ]);
348+
}
349+
350+
static ssize_t read_total_busy_show(struct device *dev,
351+
struct device_attribute *attr, char *buf)
352+
{
353+
struct ufs_hba *hba = dev_get_drvdata(dev);
354+
355+
return sysfs_emit(buf, "%llu\n",
356+
ktime_to_us(hba->monitor.total_busy[READ]));
357+
}
358+
359+
static ssize_t read_nr_requests_show(struct device *dev,
360+
struct device_attribute *attr, char *buf)
361+
{
362+
struct ufs_hba *hba = dev_get_drvdata(dev);
363+
364+
return sysfs_emit(buf, "%lu\n", hba->monitor.nr_req[READ]);
365+
}
366+
367+
static ssize_t read_req_latency_avg_show(struct device *dev,
368+
struct device_attribute *attr,
369+
char *buf)
370+
{
371+
struct ufs_hba *hba = dev_get_drvdata(dev);
372+
struct ufs_hba_monitor *m = &hba->monitor;
373+
374+
return sysfs_emit(buf, "%llu\n", div_u64(ktime_to_us(m->lat_sum[READ]),
375+
m->nr_req[READ]));
376+
}
377+
378+
static ssize_t read_req_latency_max_show(struct device *dev,
379+
struct device_attribute *attr,
380+
char *buf)
381+
{
382+
struct ufs_hba *hba = dev_get_drvdata(dev);
383+
384+
return sysfs_emit(buf, "%llu\n",
385+
ktime_to_us(hba->monitor.lat_max[READ]));
386+
}
387+
388+
static ssize_t read_req_latency_min_show(struct device *dev,
389+
struct device_attribute *attr,
390+
char *buf)
391+
{
392+
struct ufs_hba *hba = dev_get_drvdata(dev);
393+
394+
return sysfs_emit(buf, "%llu\n",
395+
ktime_to_us(hba->monitor.lat_min[READ]));
396+
}
397+
398+
static ssize_t read_req_latency_sum_show(struct device *dev,
399+
struct device_attribute *attr,
400+
char *buf)
401+
{
402+
struct ufs_hba *hba = dev_get_drvdata(dev);
403+
404+
return sysfs_emit(buf, "%llu\n",
405+
ktime_to_us(hba->monitor.lat_sum[READ]));
406+
}
407+
408+
static ssize_t write_total_sectors_show(struct device *dev,
409+
struct device_attribute *attr,
410+
char *buf)
411+
{
412+
struct ufs_hba *hba = dev_get_drvdata(dev);
413+
414+
return sysfs_emit(buf, "%lu\n", hba->monitor.nr_sec_rw[WRITE]);
415+
}
416+
417+
static ssize_t write_total_busy_show(struct device *dev,
418+
struct device_attribute *attr, char *buf)
419+
{
420+
struct ufs_hba *hba = dev_get_drvdata(dev);
421+
422+
return sysfs_emit(buf, "%llu\n",
423+
ktime_to_us(hba->monitor.total_busy[WRITE]));
424+
}
425+
426+
static ssize_t write_nr_requests_show(struct device *dev,
427+
struct device_attribute *attr, char *buf)
428+
{
429+
struct ufs_hba *hba = dev_get_drvdata(dev);
430+
431+
return sysfs_emit(buf, "%lu\n", hba->monitor.nr_req[WRITE]);
432+
}
433+
434+
static ssize_t write_req_latency_avg_show(struct device *dev,
435+
struct device_attribute *attr,
436+
char *buf)
437+
{
438+
struct ufs_hba *hba = dev_get_drvdata(dev);
439+
struct ufs_hba_monitor *m = &hba->monitor;
440+
441+
return sysfs_emit(buf, "%llu\n", div_u64(ktime_to_us(m->lat_sum[WRITE]),
442+
m->nr_req[WRITE]));
443+
}
444+
445+
static ssize_t write_req_latency_max_show(struct device *dev,
446+
struct device_attribute *attr,
447+
char *buf)
448+
{
449+
struct ufs_hba *hba = dev_get_drvdata(dev);
450+
451+
return sysfs_emit(buf, "%llu\n",
452+
ktime_to_us(hba->monitor.lat_max[WRITE]));
453+
}
454+
455+
static ssize_t write_req_latency_min_show(struct device *dev,
456+
struct device_attribute *attr,
457+
char *buf)
458+
{
459+
struct ufs_hba *hba = dev_get_drvdata(dev);
460+
461+
return sysfs_emit(buf, "%llu\n",
462+
ktime_to_us(hba->monitor.lat_min[WRITE]));
463+
}
464+
465+
static ssize_t write_req_latency_sum_show(struct device *dev,
466+
struct device_attribute *attr,
467+
char *buf)
468+
{
469+
struct ufs_hba *hba = dev_get_drvdata(dev);
470+
471+
return sysfs_emit(buf, "%llu\n",
472+
ktime_to_us(hba->monitor.lat_sum[WRITE]));
473+
}
474+
475+
static DEVICE_ATTR_RW(monitor_enable);
476+
static DEVICE_ATTR_RW(monitor_chunk_size);
477+
static DEVICE_ATTR_RO(read_total_sectors);
478+
static DEVICE_ATTR_RO(read_total_busy);
479+
static DEVICE_ATTR_RO(read_nr_requests);
480+
static DEVICE_ATTR_RO(read_req_latency_avg);
481+
static DEVICE_ATTR_RO(read_req_latency_max);
482+
static DEVICE_ATTR_RO(read_req_latency_min);
483+
static DEVICE_ATTR_RO(read_req_latency_sum);
484+
static DEVICE_ATTR_RO(write_total_sectors);
485+
static DEVICE_ATTR_RO(write_total_busy);
486+
static DEVICE_ATTR_RO(write_nr_requests);
487+
static DEVICE_ATTR_RO(write_req_latency_avg);
488+
static DEVICE_ATTR_RO(write_req_latency_max);
489+
static DEVICE_ATTR_RO(write_req_latency_min);
490+
static DEVICE_ATTR_RO(write_req_latency_sum);
491+
492+
static struct attribute *ufs_sysfs_monitor_attrs[] = {
493+
&dev_attr_monitor_enable.attr,
494+
&dev_attr_monitor_chunk_size.attr,
495+
&dev_attr_read_total_sectors.attr,
496+
&dev_attr_read_total_busy.attr,
497+
&dev_attr_read_nr_requests.attr,
498+
&dev_attr_read_req_latency_avg.attr,
499+
&dev_attr_read_req_latency_max.attr,
500+
&dev_attr_read_req_latency_min.attr,
501+
&dev_attr_read_req_latency_sum.attr,
502+
&dev_attr_write_total_sectors.attr,
503+
&dev_attr_write_total_busy.attr,
504+
&dev_attr_write_nr_requests.attr,
505+
&dev_attr_write_req_latency_avg.attr,
506+
&dev_attr_write_req_latency_max.attr,
507+
&dev_attr_write_req_latency_min.attr,
508+
&dev_attr_write_req_latency_sum.attr,
509+
NULL
510+
};
511+
512+
static const struct attribute_group ufs_sysfs_monitor_group = {
513+
.name = "monitor",
514+
.attrs = ufs_sysfs_monitor_attrs,
515+
};
516+
281517
static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
282518
enum desc_idn desc_id,
283519
u8 desc_index,
@@ -881,6 +1117,7 @@ static const struct attribute_group ufs_sysfs_attributes_group = {
8811117

8821118
static const struct attribute_group *ufs_sysfs_groups[] = {
8831119
&ufs_sysfs_default_group,
1120+
&ufs_sysfs_monitor_group,
8841121
&ufs_sysfs_device_descriptor_group,
8851122
&ufs_sysfs_interconnect_descriptor_group,
8861123
&ufs_sysfs_geometry_descriptor_group,

0 commit comments

Comments
 (0)