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:
parent
1f2737521a
commit
7ca68fa3c8
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue