irqbalance has been broken for a long time. Its ability to properly detect msi irqs and to correctly identify interrupt types (net vs. storage vs. other, etc), has been based on some tenuous string comparison logic that was easily broken by administrative name changes for interfaces. I've recently submitted this patch: https://lkml.org/lkml/2011/9/19/176 Which lets us use sysfs exclusively for finding device interrupts, which in turns lets us definitavely identify irq types (legacy pci vs. msi), as well as properly classifying them using the pci device class value. Additionally, this patch rips out the code that attemtps to bias interrupt count volumes using network statistics, since theres no sane way to be certain a single network interrupt is responsible for the number of packets received on a given interface. Workload computation is now done on soley on irq count. This may change in the future, adding /proc/stat irq and softirq time to the biasing mechanism. Note that without the above kernel change, this doesn't work right. Irqbalance contains a self check in which it identifies MSI interrupts in /proc/interrupts still. If it sees MSI irqs in /proc/interrupts, but none in sysfs, then it will issue a loud warning about irqs being missclassified until the kernel is updated. Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
115 lines
1.4 KiB
C
115 lines
1.4 KiB
C
#ifndef _INCLUDE_GUARD_TYPES_H
|
|
#define _INCLUDE_GUARD_TYPES_H
|
|
|
|
#include <glib.h>
|
|
|
|
#include "cpumask.h"
|
|
|
|
#define BALANCE_NONE 0
|
|
#define BALANCE_PACKAGE 1
|
|
#define BALANCE_CACHE 2
|
|
#define BALANCE_CORE 3
|
|
|
|
/*
|
|
* IRQ Classes
|
|
*/
|
|
#define IRQ_OTHER 0
|
|
#define IRQ_LEGACY 1
|
|
#define IRQ_SCSI 2
|
|
#define IRQ_TIMER 3
|
|
#define IRQ_ETH 4
|
|
|
|
/*
|
|
* IRQ Types
|
|
*/
|
|
#define IRQ_TYPE_LEGACY 0
|
|
#define IRQ_TYPE_MSI 1
|
|
#define IRQ_TYPE_MSIX 2
|
|
|
|
|
|
/*
|
|
* IRQ properties
|
|
*/
|
|
enum irq_prop {
|
|
IRQ_CLASS = 0,
|
|
IRQ_TYPE,
|
|
IRQ_NUMA,
|
|
IRQ_LCPU_MASK,
|
|
IRQ_MAX_PROPERTY
|
|
};
|
|
|
|
struct package {
|
|
uint64_t workload;
|
|
int number;
|
|
|
|
cpumask_t mask;
|
|
int node_num;
|
|
|
|
int class_count[7];
|
|
|
|
GList *cache_domains;
|
|
GList *interrupts;
|
|
};
|
|
|
|
struct cache_domain {
|
|
uint64_t workload;
|
|
int number;
|
|
|
|
int marker;
|
|
int node_num;
|
|
|
|
cpumask_t mask;
|
|
|
|
cpumask_t package_mask;
|
|
|
|
int class_count[7];
|
|
|
|
GList *cpu_cores;
|
|
GList *interrupts;
|
|
};
|
|
|
|
|
|
struct cpu_core {
|
|
uint64_t workload;
|
|
int number;
|
|
|
|
int marker;
|
|
int node_num;
|
|
|
|
int class_count[7];
|
|
|
|
cpumask_t package_mask;
|
|
cpumask_t cache_mask;
|
|
cpumask_t mask;
|
|
|
|
GList *interrupts;
|
|
};
|
|
|
|
struct interrupt {
|
|
uint64_t workload;
|
|
|
|
int balance_level;
|
|
|
|
int number;
|
|
int class;
|
|
int node_num;
|
|
int msi;
|
|
|
|
uint64_t count;
|
|
uint64_t old_count;
|
|
uint64_t extra;
|
|
|
|
cpumask_t mask;
|
|
cpumask_t old_mask;
|
|
|
|
|
|
cpumask_t numa_mask;
|
|
cpumask_t allowed_mask;
|
|
|
|
/* user/driver provided for smarter balancing */
|
|
cpumask_t node_mask;
|
|
};
|
|
|
|
|
|
#endif
|