Commit 7ca68fa3 authored by Dave Jiang's avatar Dave Jiang Committed by Vinod Koul
Browse files

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: default avatarDave Jiang <dave.jiang@intel.com>
Co-developed-by: default avatarFenghua Yu <fenghua.yu@intel.com>
Signed-off-by: default avatarFenghua Yu <fenghua.yu@intel.com>
Link: https://lore.kernel.org/r/20220917161222.2835172-6-fenghua.yu@intel.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 1f273752
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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
		the max value). It's visible only on platforms that support
		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.
+2 −0
Original line number Diff line number Diff line
@@ -710,6 +710,7 @@ static void idxd_groups_clear_state(struct idxd_device *idxd)
			group->tc_b = -1;
		}
		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.desc_progress_limit = group->desc_progress_limit;
		group->grpcfg.flags.batch_progress_limit = group->batch_progress_limit;
	}
}

+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ struct idxd_group {
	int tc_a;
	int tc_b;
	int desc_progress_limit;
	int batch_progress_limit;
};

struct idxd_pmu {
+3 −1
Original line number Diff line number Diff line
@@ -298,7 +298,9 @@ union group_flags {
		u64 rdbufs_allowed:8;
		u64 rsvd3:4;
		u64 desc_progress_limit:2;
		u64 rsvd4:30;
		u64 rsvd4:2;
		u64 batch_progress_limit:2;
		u64 rsvd5:26;
	};
	u64 bits;
} __packed;
+34 −2
Original line number Diff line number Diff line
@@ -474,6 +474,36 @@ static struct device_attribute dev_attr_group_desc_progress_limit =
		__ATTR(desc_progress_limit, 0644, group_desc_progress_limit_show,
		       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[] = {
	&dev_attr_group_work_queues.attr,
	&dev_attr_group_engines.attr,
@@ -486,13 +516,15 @@ static struct attribute *idxd_group_attributes[] = {
	&dev_attr_group_traffic_class_a.attr,
	&dev_attr_group_traffic_class_b.attr,
	&dev_attr_group_desc_progress_limit.attr,
	&dev_attr_group_batch_progress_limit.attr,
	NULL,
};

static bool idxd_group_attr_progress_limit_invisible(struct attribute *attr,
						     struct idxd_device *idxd)
{
	return attr == &dev_attr_group_desc_progress_limit.attr &&
	return (attr == &dev_attr_group_desc_progress_limit.attr ||
		attr == &dev_attr_group_batch_progress_limit.attr) &&
		!idxd->hw.group_cap.progress_limit;
}