@@ -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
11091113static 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+
11121154static 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+
12631313static 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