summaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2022-09-17 18:12:22 +0200
committerVinod Koul <vkoul@kernel.org>2022-09-29 19:16:08 +0200
commit7ca68fa3c8ab83dfa539f16c5b4b1aec2e33320d (patch)
treed2297934d9f37825cbe31c848cad90b86a91a9e8 /drivers/dma
parentdmaengine: idxd: add configuration for concurrent work descriptor processing (diff)
downloadlinux-7ca68fa3c8ab83dfa539f16c5b4b1aec2e33320d.tar.xz
linux-7ca68fa3c8ab83dfa539f16c5b4b1aec2e33320d.zip
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>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/idxd/device.c2
-rw-r--r--drivers/dma/idxd/idxd.h1
-rw-r--r--drivers/dma/idxd/registers.h4
-rw-r--r--drivers/dma/idxd/sysfs.c36
4 files changed, 40 insertions, 3 deletions
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
index 05a982e143fe..2c1e6f6daa62 100644
--- a/drivers/dma/idxd/device.c
+++ b/drivers/dma/idxd/device.c
@@ -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;
}
}
diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
index 7ee870e5ca67..1196ab342f01 100644
--- a/drivers/dma/idxd/idxd.h
+++ b/drivers/dma/idxd/idxd.h
@@ -97,6 +97,7 @@ struct idxd_group {
int tc_a;
int tc_b;
int desc_progress_limit;
+ int batch_progress_limit;
};
struct idxd_pmu {
diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h
index 2cc2543edd58..fe3b8d04f9db 100644
--- a/drivers/dma/idxd/registers.h
+++ b/drivers/dma/idxd/registers.h
@@ -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;
diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
index 3624bdeb71f6..bdaccf9e0436 100644
--- a/drivers/dma/idxd/sysfs.c
+++ b/drivers/dma/idxd/sysfs.c
@@ -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,14 +516,16 @@ 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 &&
- !idxd->hw.group_cap.progress_limit;
+ return (attr == &dev_attr_group_desc_progress_limit.attr ||
+ attr == &dev_attr_group_batch_progress_limit.attr) &&
+ !idxd->hw.group_cap.progress_limit;
}
static umode_t idxd_group_attr_visible(struct kobject *kobj,