132 lines
3.9 KiB
Diff
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
|
|
|