Commit 736a91b7 authored by Neil Horman's avatar Neil Horman

Make irqbalance work with Xen PV guest

This patch does two things:

1. extract IRQ name in parse_proc_interrupts() then pass it to add_new_irq()
2. do classification in add_new_irq()
Signed-off-by: 's avatarWei Liu <liuw@liuw.name>
Signed-off-by: 's avatarNeil Horman <nhorman@tuxdriver.com>
parent 9e4476fa
......@@ -18,11 +18,12 @@ char *classes[] = {
"ethernet",
"gbit-ethernet",
"10gbit-ethernet",
"virt-event",
0
};
int map_class_to_level[7] =
{ BALANCE_PACKAGE, BALANCE_CACHE, BALANCE_CACHE, BALANCE_NONE, BALANCE_CORE, BALANCE_CORE, BALANCE_CORE };
int map_class_to_level[8] =
{ BALANCE_PACKAGE, BALANCE_CACHE, BALANCE_CACHE, BALANCE_NONE, BALANCE_CORE, BALANCE_CORE, BALANCE_CORE, BALANCE_CORE };
#define MAX_CLASS 0x12
......@@ -465,7 +466,7 @@ void rebuild_irq_db(void)
}
struct irq_info *add_new_irq(int irq)
struct irq_info *add_new_irq(int irq, const char *irq_name)
{
struct irq_info *new, *nnew;
......@@ -479,8 +480,17 @@ struct irq_info *add_new_irq(int irq)
}
new->irq = irq;
new->type = IRQ_TYPE_LEGACY;
new->class = IRQ_OTHER;
/* Do classification here. As Xen PV is the first resident
* here, this is done rather simple.
*/
if (strstr(irq_name, "xen-dyn-event") != NULL) {
new->type = IRQ_TYPE_VIRT_EVENT;
new->class = IRQ_VIRT_EVENT;
} else {
new->type = IRQ_TYPE_LEGACY;
new->class = IRQ_OTHER;
}
new->level = map_class_to_level[new->class];
new->numa_node = get_numa_node(-1);
memcpy(nnew, new, sizeof(struct irq_info));
interrupts_db = g_list_append(interrupts_db, new);
......
......@@ -110,7 +110,7 @@ extern void add_banned_irq(int irq);
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);
extern struct irq_info *add_new_irq(int irq);
extern struct irq_info *add_new_irq(int irq, const char *irq_name);
#define irq_numa_node(irq) ((irq)->numa_node)
......
......@@ -59,6 +59,8 @@ void parse_proc_interrupts(void)
uint64_t count;
char *c, *c2;
struct irq_info *info;
char *irq_name, *last_token, *p, *savedptr;
char savedline[1024];
if (getline(&line, &size, file)==0)
break;
......@@ -77,15 +79,38 @@ void parse_proc_interrupts(void)
c = strchr(line, ':');
if (!c)
continue;
strncpy(savedline, line, sizeof(savedline));
*c = 0;
c++;
number = strtoul(line, NULL, 10);
/* Extract interrupt name such as "IO-APIC-fasteoi". At
* this point "savedline" is string like (note that
* special interrupts are all ignored above):
*
* 4: 150 IO-APIC-fasteoi serial
*
* The string contains at least four fields
* delineated by white spaces. The first field is
* interrupt number, followed by nr_cpus (>=1)
* interrupt counts, followed by interrupt name, then
* followed by device name.
*/
irq_name = strtok_r(savedline, " ", &savedptr);
last_token = strtok_r(NULL, " ", &savedptr);
while ((p = strtok_r(NULL, " ", &savedptr))) {
irq_name = last_token;
last_token = p;
}
info = get_irq_info(number);
if (!info) {
if (!cycle_count)
continue;
need_rescan = 1;
info = add_new_irq(number);
info = add_new_irq(number, irq_name);
}
count = 0;
......
......@@ -18,13 +18,17 @@
#define IRQ_SCSI 2
#define IRQ_TIMER 3
#define IRQ_ETH 4
#define IRQ_GBETH 5
#define IRQ_10GBETH 6
#define IRQ_VIRT_EVENT 7
/*
* IRQ Types
*/
#define IRQ_TYPE_LEGACY 0
#define IRQ_TYPE_MSI 1
#define IRQ_TYPE_MSIX 2
#define IRQ_TYPE_LEGACY 0
#define IRQ_TYPE_MSI 1
#define IRQ_TYPE_MSIX 2
#define IRQ_TYPE_VIRT_EVENT 3
enum obj_type_e {
OBJ_TYPE_CPU,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment