Skip to content

Commit f2dc327

Browse files
davejiangvinodkoul
authored andcommitted
dmaengine: idxd: add per wq PRS disable
Add sysfs knob for per wq Page Request Service disable. This knob disables PRS support for the specific wq. When this bit is set, it also overrides the wq's block on fault enabling. Tested-by: Tony Zhu <tony.zhu@intel.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Co-developed-by: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Link: https://lore.kernel.org/r/20230407203143.2189681-17-fenghua.yu@intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent a62b8f8 commit f2dc327

5 files changed

Lines changed: 74 additions & 5 deletions

File tree

Documentation/ABI/stable/sysfs-driver-dma-idxd

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,16 @@ Contact: dmaengine@vger.kernel.org
235235
Description: Indicate whether ATS disable is turned on for the workqueue.
236236
0 indicates ATS is on, and 1 indicates ATS is off for the workqueue.
237237

238+
What: /sys/bus/dsa/devices/wq<m>.<n>/prs_disable
239+
Date: Sept 14, 2022
240+
KernelVersion: 6.4.0
241+
Contact: dmaengine@vger.kernel.org
242+
Description: Controls whether PRS disable is turned on for the workqueue.
243+
0 indicates PRS is on, and 1 indicates PRS is off for the
244+
workqueue. This option overrides block_on_fault attribute
245+
if set. It's visible only on platforms that support the
246+
capability.
247+
238248
What: /sys/bus/dsa/devices/wq<m>.<n>/occupancy
239249
Date May 25, 2021
240250
KernelVersion: 5.14.0

drivers/dma/idxd/device.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -967,12 +967,16 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
967967
wq->wqcfg->priority = wq->priority;
968968

969969
if (idxd->hw.gen_cap.block_on_fault &&
970-
test_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags))
970+
test_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags) &&
971+
!test_bit(WQ_FLAG_PRS_DISABLE, &wq->flags))
971972
wq->wqcfg->bof = 1;
972973

973974
if (idxd->hw.wq_cap.wq_ats_support)
974975
wq->wqcfg->wq_ats_disable = test_bit(WQ_FLAG_ATS_DISABLE, &wq->flags);
975976

977+
if (idxd->hw.wq_cap.wq_prs_support)
978+
wq->wqcfg->wq_prs_disable = test_bit(WQ_FLAG_PRS_DISABLE, &wq->flags);
979+
976980
/* bytes 12-15 */
977981
wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes);
978982
idxd_wqcfg_set_max_batch_shift(idxd->data->type, wq->wqcfg, ilog2(wq->max_batch_size));

drivers/dma/idxd/idxd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ enum idxd_wq_flag {
143143
WQ_FLAG_DEDICATED = 0,
144144
WQ_FLAG_BLOCK_ON_FAULT,
145145
WQ_FLAG_ATS_DISABLE,
146+
WQ_FLAG_PRS_DISABLE,
146147
};
147148

148149
enum idxd_wq_type {

drivers/dma/idxd/registers.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ union wq_cap_reg {
5959
u64 occupancy:1;
6060
u64 occupancy_int:1;
6161
u64 op_config:1;
62-
u64 rsvd3:9;
62+
u64 wq_prs_support:1;
63+
u64 rsvd4:8;
6364
};
6465
u64 bits;
6566
} __packed;
@@ -371,7 +372,7 @@ union wqcfg {
371372
u32 mode:1; /* shared or dedicated */
372373
u32 bof:1; /* block on fault */
373374
u32 wq_ats_disable:1;
374-
u32 rsvd2:1;
375+
u32 wq_prs_disable:1;
375376
u32 priority:4;
376377
u32 pasid:20;
377378
u32 pasid_en:1;

drivers/dma/idxd/sysfs.c

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -822,10 +822,14 @@ static ssize_t wq_block_on_fault_store(struct device *dev,
822822
if (rc < 0)
823823
return rc;
824824

825-
if (bof)
825+
if (bof) {
826+
if (test_bit(WQ_FLAG_PRS_DISABLE, &wq->flags))
827+
return -EOPNOTSUPP;
828+
826829
set_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags);
827-
else
830+
} else {
828831
clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags);
832+
}
829833

830834
return count;
831835
}
@@ -1109,6 +1113,44 @@ static ssize_t wq_ats_disable_store(struct device *dev, struct device_attribute
11091113
static struct device_attribute dev_attr_wq_ats_disable =
11101114
__ATTR(ats_disable, 0644, wq_ats_disable_show, wq_ats_disable_store);
11111115

1116+
static ssize_t wq_prs_disable_show(struct device *dev, struct device_attribute *attr, char *buf)
1117+
{
1118+
struct idxd_wq *wq = confdev_to_wq(dev);
1119+
1120+
return sysfs_emit(buf, "%u\n", test_bit(WQ_FLAG_PRS_DISABLE, &wq->flags));
1121+
}
1122+
1123+
static ssize_t wq_prs_disable_store(struct device *dev, struct device_attribute *attr,
1124+
const char *buf, size_t count)
1125+
{
1126+
struct idxd_wq *wq = confdev_to_wq(dev);
1127+
struct idxd_device *idxd = wq->idxd;
1128+
bool prs_dis;
1129+
int rc;
1130+
1131+
if (wq->state != IDXD_WQ_DISABLED)
1132+
return -EPERM;
1133+
1134+
if (!idxd->hw.wq_cap.wq_prs_support)
1135+
return -EOPNOTSUPP;
1136+
1137+
rc = kstrtobool(buf, &prs_dis);
1138+
if (rc < 0)
1139+
return rc;
1140+
1141+
if (prs_dis) {
1142+
set_bit(WQ_FLAG_PRS_DISABLE, &wq->flags);
1143+
/* when PRS is disabled, BOF needs to be off as well */
1144+
clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags);
1145+
} else {
1146+
clear_bit(WQ_FLAG_PRS_DISABLE, &wq->flags);
1147+
}
1148+
return count;
1149+
}
1150+
1151+
static struct device_attribute dev_attr_wq_prs_disable =
1152+
__ATTR(prs_disable, 0644, wq_prs_disable_show, wq_prs_disable_store);
1153+
11121154
static ssize_t wq_occupancy_show(struct device *dev, struct device_attribute *attr, char *buf)
11131155
{
11141156
struct idxd_wq *wq = confdev_to_wq(dev);
@@ -1239,6 +1281,7 @@ static struct attribute *idxd_wq_attributes[] = {
12391281
&dev_attr_wq_max_transfer_size.attr,
12401282
&dev_attr_wq_max_batch_size.attr,
12411283
&dev_attr_wq_ats_disable.attr,
1284+
&dev_attr_wq_prs_disable.attr,
12421285
&dev_attr_wq_occupancy.attr,
12431286
&dev_attr_wq_enqcmds_retries.attr,
12441287
&dev_attr_wq_op_config.attr,
@@ -1260,6 +1303,13 @@ static bool idxd_wq_attr_max_batch_size_invisible(struct attribute *attr,
12601303
idxd->data->type == IDXD_TYPE_IAX;
12611304
}
12621305

1306+
static bool idxd_wq_attr_wq_prs_disable_invisible(struct attribute *attr,
1307+
struct idxd_device *idxd)
1308+
{
1309+
return attr == &dev_attr_wq_prs_disable.attr &&
1310+
!idxd->hw.wq_cap.wq_prs_support;
1311+
}
1312+
12631313
static umode_t idxd_wq_attr_visible(struct kobject *kobj,
12641314
struct attribute *attr, int n)
12651315
{
@@ -1273,6 +1323,9 @@ static umode_t idxd_wq_attr_visible(struct kobject *kobj,
12731323
if (idxd_wq_attr_max_batch_size_invisible(attr, idxd))
12741324
return 0;
12751325

1326+
if (idxd_wq_attr_wq_prs_disable_invisible(attr, idxd))
1327+
return 0;
1328+
12761329
return attr->mode;
12771330
}
12781331

0 commit comments

Comments
 (0)