From 8541a67cdc3cbaf5c6ed04e9a3b3e2c3f584cb33 Mon Sep 17 00:00:00 2001 From: xiahuang Date: Thu, 21 Mar 2019 19:08:17 -0400 Subject: [PATCH 2/2] feature-introduce-verifyhint-to-detect-hint-variation adapt by xiashuang xiashuang1@huawei.com when upgrade to 1.4.0 --- activate.c | 24 +++++----- classify.c | 18 ++++++-- cpumask.h | 7 +++ irqbalance.c | 135 +++++++++++++++++++++++++++++++++++++++++++------------ irqbalance.h | 5 +++ placement.c | 14 ++++++ procinterrupts.c | 57 +++++++++++++++++++++++ types.h | 1 + 8 files changed, 217 insertions(+), 44 deletions(-) diff --git a/activate.c b/activate.c index 8fd3dd0..1c4b867 100644 --- a/activate.c +++ b/activate.c @@ -61,26 +61,26 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un char buf[PATH_MAX]; FILE *file; cpumask_t applied_mask; - int valid_mask = 0; - /* - * only activate mappings for irqs that have moved - */ - if (!info->moved) + if (!info->assigned_obj) return; - if (info->assigned_obj) { - applied_mask = info->assigned_obj->mask; - valid_mask = 1; + applied_mask = info->assigned_obj->mask; + + if (hint_enabled) { + if (!cpus_empty(info->affinity_hint)) { + cpus_and(applied_mask, applied_mask, info->affinity_hint); + if (!cpus_intersects(applied_mask, unbanned_cpus)) { + log(TO_ALL, LOG_WARNING, "irq %d affinity_hint subset empty\n", info->irq); + return; + } + } } /* * Don't activate anything for which we have an invalid mask */ - if (!valid_mask || check_affinity(info, applied_mask)) - return; - - if (!info->assigned_obj) + if (check_affinity(info, applied_mask)) return; sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq); diff --git a/classify.c b/classify.c index 30a8d2a..aa391f4 100644 --- a/classify.c +++ b/classify.c @@ -66,8 +66,6 @@ struct pci_info { #define PCI_SUB_DEVICE_EMC_0568 0x0568 #define PCI_SUB_DEVICE_EMC_dd00 0xdd00 -extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused))); - /* * Apply software workarounds for some special devices * @@ -414,7 +412,7 @@ get_numa_node: fd = fopen(path, "r"); if (!fd) { cpus_setall(new->cpumask); - goto out; + goto assign_affinity_hint; } lcpu_mask = NULL; ret = getline(&lcpu_mask, &blen, fd); @@ -426,6 +424,20 @@ get_numa_node: } free(lcpu_mask); +assign_affinity_hint: + cpus_clear(new->affinity_hint); + sprintf(path, "/proc/irq/%d/affinity_hint", irq); + fd = fopen(path, "r"); + if (!fd) + goto out; + lcpu_mask = NULL; + ret = getline(&lcpu_mask, &blen, fd); + fclose(fd); + if (ret <= 0) + goto out; + cpumask_parse_user(lcpu_mask, ret, new->affinity_hint); + free(lcpu_mask); + out: log(TO_CONSOLE, LOG_INFO, "Adding IRQ %d to database\n", irq); return new; diff --git a/cpumask.h b/cpumask.h index 0774a88..8dd3703 100644 --- a/cpumask.h +++ b/cpumask.h @@ -30,6 +30,7 @@ * void cpus_xor(dst, src1, src2) dst = src1 ^ src2 * void cpus_andnot(dst, src1, src2) dst = src1 & ~src2 * void cpus_complement(dst, src) dst = ~src + * void cpumask_copy(dst, src)dst = src * * int cpus_equal(mask1, mask2) Does mask1 == mask2? * int cpus_intersects(mask1, mask2) Do mask1 and mask2 intersect? @@ -150,6 +151,12 @@ static inline void __cpus_complement(cpumask_t *dstp, bitmap_complement(dstp->bits, srcp->bits, nbits); } +#define cpumask_copy(dst, src) __cpumask_copy(&(dst), &(src), NR_CPUS) +static inline void __cpumask_copy(cpumask_t *dstp, const cpumask_t *srcp, int nbits) +{ + bitmap_copy(dstp->bits, srcp->bits, nbits); +} + #define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS) static inline int __cpus_equal(const cpumask_t *src1p, const cpumask_t *src2p, int nbits) diff --git a/irqbalance.c b/irqbalance.c index e375a1a..bf9a2e4 100644 --- a/irqbalance.c +++ b/irqbalance.c @@ -61,10 +61,38 @@ char *banscript = NULL; char *polscript = NULL; long HZ; int sleep_interval = SLEEP_INTERVAL; -GMainLoop *main_loop; +int hint_enabled = 0; +int poll_hint_interval = SLEEP_INTERVAL / 5; +unsigned int next_verify, next_balance; char *banned_cpumask_from_ui = NULL; +static inline void reset_verify_countdown(void) +{ + next_verify = poll_hint_interval; +} + +static inline void reset_balance_countdown(void) +{ + next_balance = sleep_interval; +} + +static inline int need_verify(void) +{ + return !(poll_hint_interval - next_verify); +} + +static inline int need_balance(void) +{ + return !(sleep_interval - next_balance); +} + +static inline void reset_countdown(void) +{ + reset_verify_countdown(); + reset_balance_countdown(); +} + static void sleep_approx(int seconds) { struct timespec ts; @@ -79,6 +107,26 @@ static void sleep_approx(int seconds) nanosleep(&ts, NULL); } +static void cond_sleep(void) +{ + unsigned int timeout; + + if (next_verify < next_balance) { + timeout = next_verify; + next_balance -= timeout; + reset_verify_countdown(); + } else if (next_verify > next_balance) { + timeout = next_balance; + next_verify -= timeout; + reset_balance_countdown(); + } else { + timeout = next_verify; + reset_countdown(); + } + + sleep_approx(timeout); +} + #ifdef HAVE_GETOPT_LONG struct option lopts[] = { {"oneshot", 0, NULL, 'o'}, @@ -95,14 +143,15 @@ struct option lopts[] = { {"banmod", 1 , NULL, 'm'}, {"interval", 1 , NULL, 't'}, {"version", 0, NULL, 'V'}, + {"verifyhint", 1, NULL, 'v'}, {0, 0, 0, 0} }; static void usage(void) { - log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy= | -h [exact|subset|ignore]]\n"); + log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy | -h ]\n"); log(TO_CONSOLE, LOG_INFO, " [--powerthresh= | -p | ] [--banirq= | -i ] [--banmod= | -m ] [--policyscript= | -l