irqbalance/feature-irqbalance-arm64-Add-irq-aff-change-check.patch
2019-12-25 22:08:07 +08:00

132 lines
3.9 KiB
Diff

From 0ddf835e21b4d33aba9d30755cc5674d1ee5a979 Mon Sep 17 00:00:00 2001
From: Zengruan Ye <yezengruan@huawei.com>
Date: Sat, 13 Jul 2019 19:12:29 +0800
Subject: [PATCH 2/6] feature: irqbalance: arm64: Add irq aff change check
For aarch64, the PPIs format in /proc/interrputs can be parsed
and add to interrupt db, and next, the number of interrupts
is counted and used to calculate the load. Finally these interrupts
maybe scheduled between the NUMA domains.
Acctually, the PPIs cannot change aff, and it should not be added
to interrupt db. This patch fix it.
Add a check before add a interrupt to db, just only reads the irq's
aff, and write it back to avoid any impact on the system,
According to the result of writing to fitler the irq.
Signed-off-by: wanghaibin <wanghaibin.wang@huawei.com>
---
classify.c | 7 +++++++
irqbalance.h | 3 +++
procinterrupts.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+)
diff --git a/classify.c b/classify.c
index 3a25d62..65cb4e5 100644
--- a/classify.c
+++ b/classify.c
@@ -299,6 +299,13 @@ static void add_banned_irq(int irq, GList **list, int extra_flag)
return;
}
+#ifdef AARCH64
+void add_banned_list_irq(int irq)
+{
+ add_banned_irq(irq, &banned_irqs);
+}
+#endif
+
void add_cl_banned_irq(int irq)
{
add_banned_irq(irq, &cl_banned_irqs);
diff --git a/irqbalance.h b/irqbalance.h
index 821de0e..c00430f 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -100,6 +100,9 @@ extern int get_cpu_count(void);
extern void rebuild_irq_db(void);
extern void free_irq_db(void);
extern void add_cl_banned_irq(int irq);
+#ifdef AARCH64
+extern void add_banned_list_irq(int irq);
+#endif
extern void for_each_irq(GList *list, void (*cb)(struct irq_info *info, void *data), void *data);
extern struct irq_info *get_irq_info(int irq);
extern void migrate_irq(GList **from, GList **to, struct irq_info *info);
diff --git a/procinterrupts.c b/procinterrupts.c
index 9e38e49..1f04a82 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -142,6 +142,42 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
}
+
+/*
+ * This check is only invoked at service startup, and avoid any impact on the system,
+ * The scheme just only reads the irq's aff, and write it back. According to the result
+ * of writing to fitler the irq.
+ * Return 0 means the irq can change aff. Other return values, on the contrary.
+ */
+static int is_arm_irq_aff_cannot_change(int irq)
+{
+ char buf[PATH_MAX] = { 0 };
+ FILE *file = NULL;
+ char *line = NULL;
+ size_t size = 0;
+ int ret = 0;
+
+ snprintf(buf, PATH_MAX - 1, "/proc/irq/%i/smp_affinity", irq);
+ file = fopen(buf, "r+");
+ if (!file)
+ return -1;
+
+ if (getline(&line, &size, file) <= 0) {
+ ret = -1;
+ goto out;
+ }
+
+ line[strlen(line) - 1] = '\0';
+
+ fprintf(file, "%s", line);
+ ret = fflush(file);
+
+out:
+ free(line);
+ fclose(file);
+
+ return ret;
+}
#endif
static void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq) {
char *irq_name = NULL;
@@ -233,6 +269,24 @@ GList* collect_full_irq_list()
c++;
number = strtoul(line, NULL, 10);
+#ifdef AARCH64
+ if (is_arm_irq_aff_cannot_change(number)) {
+ /*
+ * This means that the irq affinity cannot be changed, just like:
+ * (1) the irq with IRQF_PERCPU flag, per cpu irq (in arm64, like PPI)
+ * (2) the irq with IRQD_NO_BALANCING flag, some driver request irq can
+ * set the flag according to themselves require. for example in arm64,
+ * for the passthrough doorbell irq (GICV4), in future.
+ * (3) the irq with IRQD_AFFINITY_MANAGED flag, some drivers can set
+ * specially irq affinity, and prohibit user to modify it.
+ *
+ * For these irqs, we can add these to banned irq list.
+ */
+ add_banned_list_irq(number);
+ continue;
+ }
+#endif
+
info = calloc(sizeof(struct irq_info), 1);
if (info) {
init_irq_class_and_type(savedline, info, number);
--
1.8.3.1