Projects
Eulaceura:Factory
irqbalance
_service:obs_scm:feature-add-new-user-irq-polic...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:feature-add-new-user-irq-policy-config-rule.patch of Package irqbalance
From 0406d202af914881af1a6caf5247e7ac40564366 Mon Sep 17 00:00:00 2001 From: hejingxian <hejingxian@huawei.com> Date: Tue, 17 Sep 2019 23:32:54 +0800 Subject: [PATCH] add new user irq policy config rule When there is many irqs, the old user irq policy script will cost too much time. Therefore, we introduce a new user irq policy config rule which avoid policy script running for every irq. --- Makefile.am | 2 +- classify.c | 13 ++- irqbalance.c | 15 +++- irqbalance.h | 1 + placement.c | 3 +- rules_config.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++ rules_config.h | 40 +++++++++ 7 files changed, 285 insertions(+), 6 deletions(-) create mode 100644 rules_config.c create mode 100644 rules_config.h diff --git a/Makefile.am b/Makefile.am index 80d8fee..9f2be54 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,7 +42,7 @@ irqbalance_LDFLAGS = -Wl,-Bstatic endif irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \ - irqlist.c numa.c placement.c procinterrupts.c + irqlist.c numa.c placement.c procinterrupts.c rules_config.c if THERMAL irqbalance_SOURCES += thermal.c endif diff --git a/classify.c b/classify.c index dac813c..7d7a933 100644 --- a/classify.c +++ b/classify.c @@ -627,12 +627,20 @@ static void add_new_irq(char *path, struct irq_info *hint) } } /* Set NULL devpath for the irq has no sysfs entries */ - get_irq_user_policy(path, irq, &pol); + if (user_policy_list == NULL) { + get_irq_user_policy(path, irq, &pol); + } else { + memset(&pol, -1, sizeof(struct user_irq_policy)); + } if ((pol.ban == 1) || check_for_irq_ban(hint, mod)) { /*FIXME*/ add_banned_irq(irq, &banned_irqs); new = get_irq_info(irq); - } else + } else { new = add_one_irq_to_db(path, hint, &pol); + if ((new != NULL) && (user_policy_list != NULL)) { + set_usr_irq_policy(new); + } + } if (!new) log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq); @@ -782,6 +790,7 @@ int proc_irq_hotplug(char *savedline, int irq, struct irq_info **pinfo) *pinfo = get_irq_info(irq); } + if (*pinfo == NULL) { return -1; } diff --git a/irqbalance.c b/irqbalance.c index 2c9e3f3..0749f79 100644 --- a/irqbalance.c +++ b/irqbalance.c @@ -104,6 +104,7 @@ struct option lopts[] = { {"interval", 1 , NULL, 't'}, {"version", 0, NULL, 'V'}, {"migrateval", 1, NULL, 'e'}, + {"rulesconfig", 1, NULL, 'r'}, {0, 0, 0, 0} }; @@ -112,6 +113,7 @@ static void usage(void) log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j]\n"); log(TO_CONSOLE, LOG_INFO, " [--powerthresh= | -p <off> | <n>] [--banirq= | -i <n>] [--banmod= | -m <module>] [--policyscript= | -l <script>]\n"); log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--migrateval= | -e <n>]\n"); + log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>]\n"); } static void version(void) @@ -127,7 +129,7 @@ static void parse_command_line(int argc, char **argv) char *endptr; while ((opt = getopt_long(argc, argv, - "odfjVi:p:s:c:l:m:t:e:", + "odfjVi:p:s:c:l:m:t:e:r:", lopts, &longind)) != -1) { switch(opt) { @@ -203,6 +205,9 @@ static void parse_command_line(int argc, char **argv) exit(1); } break; + case 'r': + rules_config_file = strdup(optarg); + break; } } } @@ -670,6 +675,14 @@ int main(int argc, char** argv) } } + if (read_user_policy_config() != 0) { + log(TO_ALL, LOG_WARNING, "Read user policy config fail.\n"); + } + if (rules_config_file) { + free(rules_config_file); + rules_config_file = NULL; + } + build_object_tree(); if (debug_mode) dump_object_tree(); diff --git a/irqbalance.h b/irqbalance.h index e7f6b94..22940b4 100644 --- a/irqbalance.h +++ b/irqbalance.h @@ -14,6 +14,7 @@ #include "types.h" #include "config.h" +#include "rules_config.h" #ifdef __aarch64__ #define AARCH64 diff --git a/placement.c b/placement.c index 9fde8cb..43ddb81 100644 --- a/placement.c +++ b/placement.c @@ -52,8 +52,7 @@ static void find_best_object(struct topo_obj *d, void *data) * also don't consider any node that doesn't have at least one cpu in * the unbanned list */ - if ((d->obj_type == OBJ_TYPE_NODE) && - (!cpus_intersects(d->mask, unbanned_cpus))) + if (!cpus_intersects(d->mask, unbanned_cpus)) return; if (d->powersave_mode) diff --git a/rules_config.c b/rules_config.c new file mode 100644 index 0000000..0471f30 --- /dev/null +++ b/rules_config.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved. + * + * This program file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include "irqbalance.h" + +char *rules_config_file = NULL; +USER_IRQ_POLICY *user_policy_list = NULL; + +void add_usr_irq_policy(USER_IRQ_POLICY *policy) +{ + if (policy == NULL) { + return; + } + policy->next = user_policy_list; + user_policy_list = policy; +} + +char *get_irq_line(int irq) +{ + FILE *file; + char *line = NULL; + char *irq_line = NULL; + size_t size = 0; + char irq_str[20] = {0}; + char *c = NULL; + + snprintf(irq_str, 20, "%d:", irq); + + file = fopen("/proc/interrupts", "r"); + if (getline(&line, &size, file) <= 0) { + free(line); + fclose(file); + return NULL; + } + while (getline(&line, &size, file) > 0) { + c = line; + while (isblank(*(c))) + c++; + if (!isdigit(*c)) + break; + + if (!strncmp(irq_str, c, strnlen(irq_str, 20))) { + irq_line = line; + break; + } + } + + if (!irq_line) + free(line); + fclose(file); + return irq_line; +} + +USER_IRQ_POLICY *get_usr_irq_policy(char *irq_line) +{ + USER_IRQ_POLICY *p = user_policy_list; + + while (p != NULL) { + if (strstr(irq_line, p->irq_type) != NULL) { + return p; + } + p = p->next; + } + return NULL; +} + +void set_usr_irq_policy(struct irq_info *info) +{ + USER_IRQ_POLICY *user_policy; + int irq = info->irq; + char *irq_line = NULL; + + if (user_policy_list == NULL) { + return; + } + + if (irq >= 0) + irq_line = get_irq_line(irq); + if (!irq_line) + return; + + user_policy = get_usr_irq_policy(irq_line); + if (user_policy != NULL) { + if (user_policy->numa_node_set) { + info->numa_node = get_numa_node(user_policy->numa_node); + log(TO_ALL, LOG_WARNING, "override irq (%d) numa_node to %d\n", + info->irq, user_policy->numa_node); + } + if (user_policy->balance_level_set) { + info->level = user_policy->balance_level; + log(TO_ALL, LOG_WARNING, "override irq (%d) balance_level to %d\n", + info->irq, info->level); + } + } + + free(irq_line); +} + +int read_user_policy_config() +{ + FILE *file; + char *line = NULL; + size_t size = 0; + size_t len; + char *key; + char *value; + char *c; + int level; + int node = -1; + char savedline[CONFIG_LINE_MAX_LEN] = {0}; + USER_IRQ_POLICY *cur_policy = NULL; + char *levelvals[] = { "none", "package", "cache", "core" }; + + if (rules_config_file == NULL) { + return 0; + } + log(TO_ALL, LOG_INFO, "rules_config_file is: %s\n", rules_config_file); + file = fopen(rules_config_file, "r"); + if (!file) + return -1; + + while (!feof(file)) { + if (getline(&line, &size, file) <= 0) + break; + c = line; + if (*c == '#') { + continue; + } + len = strlen(line); + if (len > sizeof(savedline)-1) { + continue; + } + strncpy(savedline, line, len); + savedline[len] = '\0'; + c = savedline; + while (*c == ' ') { + c++; + } + key = c; + /* make sure there is no space near '=' */ + c = strchr(savedline, '='); + if (c != NULL) { + value = c + 1; + *c = '\0'; + } else { + continue; + } + c = strchr(value, '\n'); + if (c != NULL) { + *c = '\0'; + } + if ((strlen(key) == 0) || (strlen(value) == 0)) { + continue; + } + log(TO_ALL, LOG_INFO, "User irq policy config read: key is %s, value is %s\n", key, value); + if (strcmp(key, "type") == 0) { + cur_policy = malloc(sizeof(USER_IRQ_POLICY)); + if (cur_policy == NULL) { + goto out; + } + cur_policy->next = NULL; + cur_policy->numa_node_set = 0; + cur_policy->balance_level_set = 0; + if (strlen(value) > CONFIG_TYPE_MAX_LEN - 1) { + continue; + } + strncpy(cur_policy->irq_type, value, strlen(value) + 1); + add_usr_irq_policy(cur_policy); + } else if (strcmp(key, "balance_level") == 0) { + if (cur_policy == NULL) { + goto out; + } + for (level = 0; level < MAX_LEVEL_NUM; level++) { + if (strcasecmp(value, levelvals[level]) == 0) { + break; + } + } + if (level >= MAX_LEVEL_NUM) { + log(TO_ALL, LOG_WARNING, "Bad value for balance_level policy: %s\n", value); + } else { + cur_policy->balance_level = level; + cur_policy->balance_level_set = 1; + } + } else if (strcmp(key, "numa_node") == 0) { + if (cur_policy == NULL) { + goto out; + } + node = strtoul(value, NULL, 10); + /* check node */ + if (node != -1 && !get_numa_node(node)) { + log(TO_ALL, LOG_WARNING, "NUMA node %d doesn't exist\n", + node); + continue; + } + cur_policy->numa_node = node; + cur_policy->numa_node_set = 1; + } + } +out: + fclose(file); + if (line) { + free(line); + } + return 0; +} diff --git a/rules_config.h b/rules_config.h new file mode 100644 index 0000000..42f539d --- /dev/null +++ b/rules_config.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved. + * + * This program file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _INCLUDE_RULES_CONFIG_H +#define _INCLUDE_RULES_CONFIG_H + +#define CONFIG_TYPE_MAX_LEN 32 +#define CONFIG_LINE_MAX_LEN 512 +#define MAX_LEVEL_NUM 4 + +typedef struct user_irq_policy_config { + char irq_type[CONFIG_TYPE_MAX_LEN]; + int numa_node; + int balance_level; + int numa_node_set; + int balance_level_set; + struct user_irq_policy_config *next; +}USER_IRQ_POLICY; +extern USER_IRQ_POLICY *user_policy_list; +extern char *rules_config_file; + +void add_usr_irq_policy(USER_IRQ_POLICY *policy); + +USER_IRQ_POLICY *get_usr_irq_policy(char *name); + +int read_user_policy_config(); + +void set_usr_irq_policy(struct irq_info *info); + +#endif -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2