Skip to content

Commit

Permalink
arm64: Add irq aff change check
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
liuchao173 committed Mar 12, 2020
1 parent 654f9c5 commit 55294ce
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
7 changes: 7 additions & 0 deletions classify.c
Expand Up @@ -280,6 +280,13 @@ static void add_banned_irq(int irq, GList **list)
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);
Expand Down
3 changes: 3 additions & 0 deletions irqbalance.h
Expand Up @@ -101,6 +101,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);
Expand Down
48 changes: 48 additions & 0 deletions procinterrupts.c
Expand Up @@ -143,6 +143,36 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)


}

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

GList* collect_full_irq_list()
Expand Down Expand Up @@ -214,6 +244,24 @@ GList* collect_full_irq_list()
*c = 0;
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(1, sizeof(struct irq_info));
if (info) {
info->irq = number;
Expand Down

0 comments on commit 55294ce

Please sign in to comment.