From: Zhou Guanghui zhouguanghui1@huawei.com
ascend inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------------------------------
The iopf workqueue which means IO Page Fault workqueue is used for device page fault.
During the processing of the iopf work, the handle_mm_fault() is invoked to alloc page and create a mapping. It is expected that the CPU that allocates memory and the device that triggers the fault are affinity to the same NUMA node to ensure that the memory allocated is local access to CPU and device. This will also improve the performance.
Signed-off-by: Zhou Guanghui zhouguanghui1@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/Kconfig | 13 +++++++++++++ drivers/iommu/io-pgfault.c | 22 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 4412f14547af..8842402e302d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1362,6 +1362,19 @@ config ASCEND_OOM 0: disable oom killer 1: enable oom killer (default,compatible with mainline) 2: disable oom killer and panic on oom + +config ASCEND_IOPF_HIPRI + bool "Enable support for highpri iopf workqueue" + default y + depends on IOMMU_PAGE_FAULT + help + The iopf workqueue which means IO Page Fault workqueue is used for device + page fault. + + This option enable the high priority for iopf workqueue. If enabled, the + CPU which processes IOPF work is the same as that which processes IOPF + event interrupts. + endif
endmenu diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c index 9025e50dff66..271400633dae 100644 --- a/drivers/iommu/io-pgfault.c +++ b/drivers/iommu/io-pgfault.c @@ -48,6 +48,8 @@ struct iopf_group { struct work_struct work; };
+static int enable_iopf_hipri __read_mostly; + static int iopf_complete(struct device *dev, struct iommu_fault_event *evt, enum page_response_code status) { @@ -399,6 +401,7 @@ struct iopf_queue * iopf_queue_alloc(const char *name, iopf_queue_flush_t flush, void *cookie) { struct iopf_queue *queue; + unsigned int type = WQ_UNBOUND;
queue = kzalloc(sizeof(*queue), GFP_KERNEL); if (!queue) @@ -410,7 +413,10 @@ iopf_queue_alloc(const char *name, iopf_queue_flush_t flush, void *cookie) * that's dealt with, the high-level function can handle groups out of * order. */ - queue->wq = alloc_workqueue("iopf_queue/%s", WQ_UNBOUND, 0, name); + if (enable_iopf_hipri) + type = WQ_HIGHPRI; + + queue->wq = alloc_workqueue("iopf_queue/%s", type, 0, name); if (!queue->wq) { kfree(queue); return NULL; @@ -442,3 +448,17 @@ void iopf_queue_free(struct iopf_queue *queue) kfree(queue); } EXPORT_SYMBOL_GPL(iopf_queue_free); + +#ifdef CONFIG_ASCEND_IOPF_HIPRI + +static int __init ascend_enable_iopf_hipri(char *s) +{ + enable_iopf_hipri = 1; + + pr_info("Ascend enable iopf workqueue highpri\n"); + + return 1; +} +__setup("enable_iopf_hipri", ascend_enable_iopf_hipri); + +#endif