dmaengine: idxd: add configuration for concurrent batch descriptor processing

Add sysfs knob to allow control of the number of batch descriptors that can
be concurrently processed by an engine in the group as a fraction of the
Maximum Work Descriptors in Progress value specfied in ENGCAP register.
This control knob is part of toggle for QoS control.

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/20220917161222.2835172-6-fenghua.yu@intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Dave Jiang 2022-09-17 09:12:22 -07:00 committed by Vinod Koul
parent 1f2737521a
commit 7ca68fa3c8
5 changed files with 52 additions and 3 deletions

View File

@ -278,3 +278,15 @@ Description: Allows control of the number of work descriptors that can be
1 (1/2 of max value), 2 (1/4 of the max value), and 3 (1/8 of 1 (1/2 of max value), 2 (1/4 of the max value), and 3 (1/8 of
the max value). It's visible only on platforms that support the max value). It's visible only on platforms that support
the capability. the capability.
What: /sys/bus/dsa/devices/group<m>.<n>/batch_progress_limit
Date: Sept 14, 2022
KernelVersion: 6.0.0
Contact: dmaengine@vger.kernel.org
Description: Allows control of the number of batch descriptors that can be
concurrently processed by an engine in the group as a fraction
of the Maximum Batch Descriptors in Progress value specified in
the ENGCAP register. The acceptable values are 0 (default),
1 (1/2 of max value), 2 (1/4 of the max value), and 3 (1/8 of
the max value). It's visible only on platforms that support
the capability.

View File

@ -710,6 +710,7 @@ static void idxd_groups_clear_state(struct idxd_device *idxd)
group->tc_b = -1; group->tc_b = -1;
} }
group->desc_progress_limit = 0; group->desc_progress_limit = 0;
group->batch_progress_limit = 0;
} }
} }
@ -932,6 +933,7 @@ static void idxd_group_flags_setup(struct idxd_device *idxd)
group->grpcfg.flags.rdbufs_allowed = idxd->max_rdbufs; group->grpcfg.flags.rdbufs_allowed = idxd->max_rdbufs;
group->grpcfg.flags.desc_progress_limit = group->desc_progress_limit; group->grpcfg.flags.desc_progress_limit = group->desc_progress_limit;
group->grpcfg.flags.batch_progress_limit = group->batch_progress_limit;
} }
} }

View File

@ -97,6 +97,7 @@ struct idxd_group {
int tc_a; int tc_a;
int tc_b; int tc_b;
int desc_progress_limit; int desc_progress_limit;
int batch_progress_limit;
}; };
struct idxd_pmu { struct idxd_pmu {

View File

@ -298,7 +298,9 @@ union group_flags {
u64 rdbufs_allowed:8; u64 rdbufs_allowed:8;
u64 rsvd3:4; u64 rsvd3:4;
u64 desc_progress_limit:2; u64 desc_progress_limit:2;
u64 rsvd4:30; u64 rsvd4:2;
u64 batch_progress_limit:2;
u64 rsvd5:26;
}; };
u64 bits; u64 bits;
} __packed; } __packed;

View File

@ -474,6 +474,36 @@ static struct device_attribute dev_attr_group_desc_progress_limit =
__ATTR(desc_progress_limit, 0644, group_desc_progress_limit_show, __ATTR(desc_progress_limit, 0644, group_desc_progress_limit_show,
group_desc_progress_limit_store); group_desc_progress_limit_store);
static ssize_t group_batch_progress_limit_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct idxd_group *group = confdev_to_group(dev);
return sysfs_emit(buf, "%d\n", group->batch_progress_limit);
}
static ssize_t group_batch_progress_limit_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct idxd_group *group = confdev_to_group(dev);
int val, rc;
rc = kstrtoint(buf, 10, &val);
if (rc < 0)
return -EINVAL;
if (val & ~GENMASK(1, 0))
return -EINVAL;
group->batch_progress_limit = val;
return count;
}
static struct device_attribute dev_attr_group_batch_progress_limit =
__ATTR(batch_progress_limit, 0644, group_batch_progress_limit_show,
group_batch_progress_limit_store);
static struct attribute *idxd_group_attributes[] = { static struct attribute *idxd_group_attributes[] = {
&dev_attr_group_work_queues.attr, &dev_attr_group_work_queues.attr,
&dev_attr_group_engines.attr, &dev_attr_group_engines.attr,
@ -486,14 +516,16 @@ static struct attribute *idxd_group_attributes[] = {
&dev_attr_group_traffic_class_a.attr, &dev_attr_group_traffic_class_a.attr,
&dev_attr_group_traffic_class_b.attr, &dev_attr_group_traffic_class_b.attr,
&dev_attr_group_desc_progress_limit.attr, &dev_attr_group_desc_progress_limit.attr,
&dev_attr_group_batch_progress_limit.attr,
NULL, NULL,
}; };
static bool idxd_group_attr_progress_limit_invisible(struct attribute *attr, static bool idxd_group_attr_progress_limit_invisible(struct attribute *attr,
struct idxd_device *idxd) struct idxd_device *idxd)
{ {
return attr == &dev_attr_group_desc_progress_limit.attr && return (attr == &dev_attr_group_desc_progress_limit.attr ||
!idxd->hw.group_cap.progress_limit; attr == &dev_attr_group_batch_progress_limit.attr) &&
!idxd->hw.group_cap.progress_limit;
} }
static umode_t idxd_group_attr_visible(struct kobject *kobj, static umode_t idxd_group_attr_visible(struct kobject *kobj,