From eb9bad98d0c01f9d44a7b4bb85a67fe1ec998888 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Wed, 5 Sep 2012 07:07:29 +0200 Subject: [PATCH] irqbalance: update to 1.0.4. --- .../patches/irqbalance-2011-08-09.patch | 1584 ----------------- srcpkgs/irqbalance/template | 16 +- 2 files changed, 5 insertions(+), 1595 deletions(-) delete mode 100644 srcpkgs/irqbalance/patches/irqbalance-2011-08-09.patch diff --git a/srcpkgs/irqbalance/patches/irqbalance-2011-08-09.patch b/srcpkgs/irqbalance/patches/irqbalance-2011-08-09.patch deleted file mode 100644 index 45060a95d1..0000000000 --- a/srcpkgs/irqbalance/patches/irqbalance-2011-08-09.patch +++ /dev/null @@ -1,1584 +0,0 @@ -diff --git a/ChangeLog b/ChangeLog -deleted file mode 100644 -index f5e9428..0000000 ---- a/ChangeLog -+++ /dev/null -@@ -1,3 +0,0 @@ --This is all tracked in the SVN repo. This file is just here to keep the --autotools from complaining -- -diff --git a/Makefile.am b/Makefile.am -index 9847232..188e34f 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -22,17 +22,17 @@ - - AUTOMAKE_OPTIONS = no-dependencies - ACLOCAL_AMFLAGS = -I m4 --EXTRA_DIST = README INSTALL COPYING autogen.sh m4/cap-ng.m4 misc/irqbalance.service -- -+EXTRA_DIST = INSTALL COPYING autogen.sh misc/irqbalance.service -+ - INCLUDES = -I${top_srcdir} --LIBS = $(CAPNG_LDADD) $(GLIB_LIBS) @LIBS@ --AM_CFLAGS = $(GLIB_CFLAGS) -+AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB_CFLAGS) - AM_CPPFLAGS = -W -Wall -Wshadow -Wformat -Wundef -D_GNU_SOURCE - noinst_HEADERS = bitmap.h constants.h cpumask.h irqbalance.h non-atomic.h \ - types.h - sbin_PROGRAMS = irqbalance - irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \ -- irqlist.c numa.c placement.c powermode.c procinterrupts.c -+ irqlist.c numa.c placement.c procinterrupts.c -+irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB_LIBS) - dist_man_MANS = irqbalance.1 - - CONFIG_CLEAN_FILES = debug*.list config/* -@@ -40,3 +40,6 @@ clean-generic: - rm -rf autom4te*.cache - rm -f *.rej *.orig *~ - -+if LOCAL_GLIB -+SUBDIRS = glib-local -+endif -diff --git a/NEWS b/NEWS -deleted file mode 100644 -index 7cc0277..0000000 ---- a/NEWS -+++ /dev/null -@@ -1 +0,0 @@ --No news currently -diff --git a/README b/README -deleted file mode 100644 -index e69de29..0000000 -diff --git a/activate.c b/activate.c -index 292c44a..02fc8dc 100644 ---- a/activate.c -+++ b/activate.c -@@ -1,5 +1,6 @@ - /* - * Copyright (C) 2006, Intel Corporation -+ * Copyright (C) 2012, Neil Horman - * - * This file is part of irqbalance - * -@@ -31,34 +32,63 @@ - - #include "irqbalance.h" - -+static int check_affinity(struct irq_info *info, cpumask_t applied_mask) -+{ -+ cpumask_t current_mask; -+ char buf[PATH_MAX]; -+ char *line = NULL; -+ size_t size = 0; -+ FILE *file; -+ -+ sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq); -+ file = fopen(buf, "r"); -+ if (!file) -+ return 1; -+ if (getline(&line, &size, file)==0) { -+ free(line); -+ fclose(file); -+ return 1; -+ } -+ cpumask_parse_user(line, strlen(line), current_mask); -+ fclose(file); -+ free(line); -+ -+ return cpus_equal(applied_mask, current_mask); -+} - - static void activate_mapping(struct irq_info *info, void *data __attribute__((unused))) - { - char buf[PATH_MAX]; - FILE *file; - cpumask_t applied_mask; -+ int valid_mask = 0; -+ -+ if ((hint_policy == HINT_POLICY_EXACT) && -+ (!cpus_empty(info->affinity_hint))) { -+ applied_mask = info->affinity_hint; -+ valid_mask = 1; -+ } else if (info->assigned_obj) { -+ applied_mask = info->assigned_obj->mask; -+ valid_mask = 1; -+ if ((hint_policy == HINT_POLICY_SUBSET) && -+ (!cpus_empty(info->affinity_hint))) -+ cpus_and(applied_mask, applied_mask, info->affinity_hint); -+ } - - /* - * only activate mappings for irqs that have moved - */ -- if (!info->moved) -+ if (!info->moved && (!valid_mask || check_affinity(info, applied_mask))) - return; - - if (!info->assigned_obj) - return; - -- - sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq); - file = fopen(buf, "w"); - if (!file) - return; - -- if ((hint_policy == HINT_POLICY_EXACT) && -- (!cpus_empty(info->affinity_hint))) -- applied_mask = info->affinity_hint; -- else -- applied_mask = info->assigned_obj->mask; -- - cpumask_scnprintf(buf, PATH_MAX, applied_mask); - fprintf(file, "%s", buf); - fclose(file); -diff --git a/autogen.sh b/autogen.sh -index 5ad9f14..b792e8b 100755 ---- a/autogen.sh -+++ b/autogen.sh -@@ -1,4 +1,5 @@ - #! /bin/sh - set -x -e -+mkdir -p m4 - # --no-recursive is available only in recent autoconf versions - autoreconf -fv --install -diff --git a/classify.c b/classify.c -index 124dab0..05b3bfb 100644 ---- a/classify.c -+++ b/classify.c -@@ -52,6 +52,8 @@ static short class_codes[MAX_CLASS] = { - }; - - static GList *interrupts_db; -+static GList *new_irq_list; -+static GList *banned_irqs; - - #define SYSDEV_DIR "/sys/bus/pci/devices" - -@@ -63,6 +65,30 @@ static gint compare_ints(gconstpointer a, gconstpointer b) - return ai->irq - bi->irq; - } - -+void add_banned_irq(int irq) -+{ -+ struct irq_info find, *new; -+ GList *entry; -+ -+ find.irq = irq; -+ entry = g_list_find_custom(banned_irqs, &find, compare_ints); -+ if (entry) -+ return; -+ -+ new = calloc(sizeof(struct irq_info), 1); -+ if (!new) { -+ if (debug_mode) -+ printf("No memory to ban irq %d\n", irq); -+ return; -+ } -+ -+ new->irq = irq; -+ -+ banned_irqs = g_list_append(banned_irqs, new); -+ return; -+} -+ -+ - /* - * Inserts an irq_info struct into the intterupts_db list - * devpath points to the device directory in sysfs for the -@@ -90,6 +116,13 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, int irq) - return NULL; - } - -+ entry = g_list_find_custom(banned_irqs, &find, compare_ints); -+ if (entry) { -+ if (debug_mode) -+ printf("SKIPPING BANNED IRQ %d\n", irq); -+ return NULL; -+ } -+ - new = calloc(sizeof(struct irq_info), 1); - if (!new) - return NULL; -@@ -175,6 +208,43 @@ out: - return new; - } - -+static int check_for_irq_ban(char *path, int irq) -+{ -+ char *cmd; -+ int rc; -+ -+ if (!banscript) -+ return 0; -+ -+ cmd = alloca(strlen(path)+strlen(banscript)+32); -+ if (!cmd) -+ return 0; -+ -+ sprintf(cmd, "%s %s %d",banscript, path, irq); -+ rc = system(cmd); -+ -+ /* -+ * The system command itself failed -+ */ -+ if (rc == -1) { -+ if (debug_mode) -+ printf("%s failed, please check the --banscript option\n", cmd); -+ else -+ syslog(LOG_INFO, "%s failed, please check the --banscript option\n", cmd); -+ return 0; -+ } -+ -+ if (WEXITSTATUS(rc)) { -+ if (debug_mode) -+ printf("irq %d is baned by %s\n", irq, banscript); -+ else -+ syslog(LOG_INFO, "irq %d is baned by %s\n", irq, banscript); -+ return 1; -+ } -+ return 0; -+ -+} -+ - /* - * Figures out which interrupt(s) relate to the device we're looking at in dirname - */ -@@ -199,6 +269,10 @@ static void build_one_dev_entry(const char *dirname) - irqnum = strtol(entry->d_name, NULL, 10); - if (irqnum) { - sprintf(path, "%s/%s", SYSDEV_DIR, dirname); -+ if (check_for_irq_ban(path, irqnum)) { -+ add_banned_irq(irqnum); -+ continue; -+ } - new = add_one_irq_to_db(path, irqnum); - if (!new) - continue; -@@ -221,6 +295,11 @@ static void build_one_dev_entry(const char *dirname) - */ - if (irqnum) { - sprintf(path, "%s/%s", SYSDEV_DIR, dirname); -+ if (check_for_irq_ban(path, irqnum)) { -+ add_banned_irq(irqnum); -+ goto done; -+ } -+ - new = add_one_irq_to_db(path, irqnum); - if (!new) - goto done; -@@ -248,6 +327,8 @@ void rebuild_irq_db(void) - { - DIR *devdir = opendir(SYSDEV_DIR); - struct dirent *entry; -+ GList *gentry; -+ struct irq_info *ninfo, *iinfo; - - free_irq_db(); - -@@ -263,22 +344,46 @@ void rebuild_irq_db(void) - build_one_dev_entry(entry->d_name); - - } while (entry != NULL); -+ - closedir(devdir); -+ -+ if (!new_irq_list) -+ return; -+ gentry = g_list_first(new_irq_list); -+ while(gentry) { -+ ninfo = gentry->data; -+ iinfo = get_irq_info(ninfo->irq); -+ new_irq_list = g_list_remove(gentry, ninfo); -+ if (!iinfo) { -+ if (debug_mode) -+ printf("Adding untracked IRQ %d to database\n", ninfo->irq); -+ interrupts_db = g_list_append(interrupts_db, ninfo); -+ } else -+ free(ninfo); -+ -+ gentry = g_list_first(new_irq_list); -+ } -+ g_list_free(new_irq_list); -+ new_irq_list = NULL; -+ - } - --struct irq_info *add_misc_irq(int irq) -+struct irq_info *add_new_irq(int irq) - { -- struct irq_info *new; -+ struct irq_info *new, *nnew; - - new = calloc(sizeof(struct irq_info), 1); -- if (!new) -+ nnew = calloc(sizeof(struct irq_info), 1); -+ if (!new || !nnew) - return NULL; - - new->irq = irq; - new->type = IRQ_TYPE_LEGACY; - new->class = IRQ_OTHER; - new->numa_node = get_numa_node(-1); -+ memcpy(nnew, new, sizeof(struct irq_info)); - interrupts_db = g_list_append(interrupts_db, new); -+ new_irq_list = g_list_append(new_irq_list, nnew); - return new; - } - -@@ -307,7 +412,7 @@ struct irq_info *get_irq_info(int irq) - void migrate_irq(GList **from, GList **to, struct irq_info *info) - { - GList *entry; -- struct irq_info find, *tmp;; -+ struct irq_info find, *tmp; - - find.irq = info->irq; - entry = g_list_find_custom(*from, &find, compare_ints); -@@ -325,18 +430,9 @@ static gint sort_irqs(gconstpointer A, gconstpointer B) - a = (struct irq_info*)A; - b = (struct irq_info*)B; - -- if (a->class < b->class) -- return 1; -- if (a->class > b->class) -- return -1; -- if (a->load < b->load) -- return 1; -- if (a->load > b->load) -- return -1; -- if (aclass < b->class || a->load < b->load || a < b) - return 1; - return -1; -- - } - - void sort_irq_list(GList **list) -diff --git a/configure.ac b/configure.ac -index eed55ba..1230d66 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1,49 +1,12 @@ --dnl --define([AC_INIT_NOTICE], --[### Generated automatically using autoconf version] AC_ACVERSION [ --### Copyright 2009 Steve Grubb --### --### Permission is hereby granted, free of charge, to any person obtaining a --### copy of this software and associated documentation files (the "Software"), --### to deal in the Software without restriction, including without limitation --### the rights to use, copy, modify, merge, publish, distribute, sublicense, --### and/or sell copies of the Software, and to permit persons to whom the --### Software is furnished to do so, subject to the following conditions: --### --### The above copyright notice and this permission notice shall be included --### in all copies or substantial portions of the Software. --### --### THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --### IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --### FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL --### THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR --### OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, --### ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR --### OTHER DEALINGS IN THE SOFTWARE. --### --### For usage, run `./configure --help' --### For more detailed information on installation, read the file `INSTALL'. --### --### If configuration succeeds, status is in the file `config.status'. --### A log of configuration tests is in `config.log'. --]) -- --AC_REVISION($Revision: 1.3 $)dnl - AC_INIT(irqbalance,1.0.3) - AC_PREREQ(2.12)dnl - AM_CONFIG_HEADER(config.h) - --echo Configuring irqbalance $VERSION -- - AC_CONFIG_MACRO_DIR([m4]) --AC_CANONICAL_TARGET --AM_INIT_AUTOMAKE -+AM_INIT_AUTOMAKE([foreign]) - AM_PROG_LIBTOOL - AC_SUBST(LIBTOOL_DEPS) - --AC_MSG_NOTICE() --AC_MSG_NOTICE([Checking for programs]) -- - AC_PROG_CC - AC_PROG_INSTALL - AC_PROG_AWK -@@ -55,9 +18,6 @@ AS_IF([test "$enable_numa" = "no"],[ - ac_cv_lib_numa_numa_available=no - ]) - --AC_MSG_NOTICE --AC_MSG_NOTICE([echo Checking for header files]) -- - AC_HEADER_STDC - AC_CHECK_HEADERS([numa.h]) - -@@ -70,10 +30,57 @@ AC_C_CONST - AC_C_INLINE - AM_PROG_CC_C_O - --PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.28]) --LIBCAP_NG_PATH -+AC_ARG_WITH([glib2], -+ [AS_HELP_STRING([--without-glib2], -+ [Don't use system glib2 library. Use local implementation instead.])], -+ [], -+ [with_glib2=check]) -+ -+local_glib2= -+AS_IF( -+ [test "x$with_glib2" = xyes], -+ [PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.28])], -+ -+ [test "x$with_glib2" = xno], -+ [local_glib2="yes"], -+ -+ [PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.28], [], [local_glib2="yes"])] -+) -+ -+AS_IF( -+ [test "x$local_glib2" = xyes], -+ [ -+ GLIB_CFLAGS=-I./glib-local -+ GLIB_LIBS=glib-local/libglib.a -+ AC_SUBST(GLIB_CFLAGS) -+ AC_SUBST(GLIB_LIBS) -+ AC_MSG_WARN(Using locale implementation of GList functions) -+ ] -+) -+ -+AM_CONDITIONAL([LOCAL_GLIB], [test "x$local_glib2" = "xyes"]) -+ -+AC_ARG_WITH([libcap-ng], -+ AS_HELP_STRING([libcap-ng], [Add libcap-ng-support @<:@default=auto@:>@])) -+ -+AS_IF( -+ [test "x$libcap_ng" != "xno"], -+ [ -+ PKG_CHECK_MODULES([LIBCAP_NG], [libcap-ng], -+ [AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])], -+ [ -+ AS_IF( -+ [test "x$libcap_ng" = "xyes"], -+ [ -+ AC_MSG_ERROR([libcap-ng not found]) -+ ] -+ ) -+ ] -+ ) -+ ] -+) - --AC_OUTPUT(Makefile) -+AC_OUTPUT(Makefile glib-local/Makefile) - - AC_MSG_NOTICE() - AC_MSG_NOTICE([irqbalance Version: $VERSION]) -diff --git a/cputree.c b/cputree.c -index af4fd3a..9568967 100644 ---- a/cputree.c -+++ b/cputree.c -@@ -1,5 +1,6 @@ - /* - * Copyright (C) 2006, Intel Corporation -+ * Copyright (C) 2012, Neil Horman - * - * This file is part of irqbalance - * -diff --git a/glib-local/Makefile.am b/glib-local/Makefile.am -new file mode 100644 -index 0000000..336b56e ---- /dev/null -+++ b/glib-local/Makefile.am -@@ -0,0 +1,8 @@ -+## Process this file with automake to produce Makefile.in -+noinst_LIBRARIES = libglib.a -+ -+libglib_a_SOURCES = glist.c -+ -+libglib_a_CFLAGS = @GLIB_CFLAGS@ -+ -+noinst_HEADERS = glib.h glist.h -diff --git a/glib-local/glib.h b/glib-local/glib.h -new file mode 100644 -index 0000000..5874892 ---- /dev/null -+++ b/glib-local/glib.h -@@ -0,0 +1 @@ -+#include -diff --git a/glib-local/glist.c b/glib-local/glist.c -new file mode 100644 -index 0000000..6fa1761 ---- /dev/null -+++ b/glib-local/glist.c -@@ -0,0 +1,381 @@ -+#include -+ -+#include "glist.h" -+ -+/** -+ * g_list_free: -+ * @list: a #GList -+ * -+ * Frees all of the memory used by a #GList. -+ * The freed elements are returned to the slice allocator. -+ * -+ * -+ * If list elements contain dynamically-allocated memory, -+ * you should either use g_list_free_full() or free them manually -+ * first. -+ * -+ */ -+void -+g_list_free (GList *list) -+{ -+ GList *l = list; -+ -+ while(l) { -+ GList *tmp = l->next; -+ free(l); -+ l = tmp; -+ } -+} -+ -+/** -+ * g_list_last: -+ * @list: a #GList -+ * -+ * Gets the last element in a #GList. -+ * -+ * Returns: the last element in the #GList, -+ * or %NULL if the #GList has no elements -+ */ -+GList* -+g_list_last (GList *list) -+{ -+ if (list) -+ { -+ while (list->next) -+ list = list->next; -+ } -+ -+ return list; -+} -+ -+/** -+ * g_list_append: -+ * @list: a pointer to a #GList -+ * @data: the data for the new element -+ * -+ * Adds a new element on to the end of the list. -+ * -+ * -+ * The return value is the new start of the list, which -+ * may have changed, so make sure you store the new value. -+ * -+ * -+ * -+ * Note that g_list_append() has to traverse the entire list -+ * to find the end, which is inefficient when adding multiple -+ * elements. A common idiom to avoid the inefficiency is to prepend -+ * the elements and reverse the list when all elements have been added. -+ * -+ * -+ * |[ -+ * /* Notice that these are initialized to the empty list. */ -+ * GList *list = NULL, *number_list = NULL; -+ * -+ * /* This is a list of strings. */ -+ * list = g_list_append (list, "first"); -+ * list = g_list_append (list, "second"); -+ * -+ * /* This is a list of integers. */ -+ * number_list = g_list_append (number_list, GINT_TO_POINTER (27)); -+ * number_list = g_list_append (number_list, GINT_TO_POINTER (14)); -+ * ]| -+ * -+ * Returns: the new start of the #GList -+ */ -+GList* -+g_list_append (GList *list, -+ gpointer data) -+{ -+ GList *new_list; -+ GList *last; -+ -+ new_list = malloc(sizeof(*new_list)); -+ new_list->data = data; -+ new_list->next = NULL; -+ -+ if (list) -+ { -+ last = g_list_last (list); -+ /* g_assert (last != NULL); */ -+ last->next = new_list; -+ new_list->prev = last; -+ -+ return list; -+ } -+ else -+ { -+ new_list->prev = NULL; -+ return new_list; -+ } -+} -+ -+static inline GList* -+_g_list_remove_link (GList *list, -+ GList *link) -+{ -+ if (link) -+ { -+ if (link->prev) -+ link->prev->next = link->next; -+ if (link->next) -+ link->next->prev = link->prev; -+ -+ if (link == list) -+ list = list->next; -+ -+ link->next = NULL; -+ link->prev = NULL; -+ } -+ -+ return list; -+} -+ -+/** -+ * g_list_delete_link: -+ * @list: a #GList -+ * @link_: node to delete from @list -+ * -+ * Removes the node link_ from the list and frees it. -+ * Compare this to g_list_remove_link() which removes the node -+ * without freeing it. -+ * -+ * Returns: the new head of @list -+ */ -+GList* -+g_list_delete_link (GList *list, -+ GList *link_) -+{ -+ list = _g_list_remove_link (list, link_); -+ free (link_); -+ -+ return list; -+} -+ -+/** -+ * g_list_first: -+ * @list: a #GList -+ * -+ * Gets the first element in a #GList. -+ * -+ * Returns: the first element in the #GList, -+ * or %NULL if the #GList has no elements -+ */ -+GList* -+g_list_first (GList *list) -+{ -+ if (list) -+ { -+ while (list->prev) -+ list = list->prev; -+ } -+ -+ return list; -+} -+ -+static GList * -+g_list_sort_merge (GList *l1, -+ GList *l2, -+ GFunc compare_func, -+ gpointer user_data) -+{ -+ GList list, *l, *lprev; -+ gint cmp; -+ -+ l = &list; -+ lprev = NULL; -+ -+ while (l1 && l2) -+ { -+ cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data); -+ -+ if (cmp <= 0) -+ { -+ l->next = l1; -+ l1 = l1->next; -+ } -+ else -+ { -+ l->next = l2; -+ l2 = l2->next; -+ } -+ l = l->next; -+ l->prev = lprev; -+ lprev = l; -+ } -+ l->next = l1 ? l1 : l2; -+ l->next->prev = l; -+ -+ return list.next; -+} -+ -+static GList* -+g_list_sort_real (GList *list, -+ GFunc compare_func, -+ gpointer user_data) -+{ -+ GList *l1, *l2; -+ -+ if (!list) -+ return NULL; -+ if (!list->next) -+ return list; -+ -+ l1 = list; -+ l2 = list->next; -+ -+ while ((l2 = l2->next) != NULL) -+ { -+ if ((l2 = l2->next) == NULL) -+ break; -+ l1 = l1->next; -+ } -+ l2 = l1->next; -+ l1->next = NULL; -+ -+ return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data), -+ g_list_sort_real (l2, compare_func, user_data), -+ compare_func, -+ user_data); -+} -+ -+/** -+ * g_list_sort: -+ * @list: a #GList -+ * @compare_func: the comparison function used to sort the #GList. -+ * This function is passed the data from 2 elements of the #GList -+ * and should return 0 if they are equal, a negative value if the -+ * first element comes before the second, or a positive value if -+ * the first element comes after the second. -+ * -+ * Sorts a #GList using the given comparison function. -+ * -+ * Returns: the start of the sorted #GList -+ */ -+/** -+ * GCompareFunc: -+ * @a: a value. -+ * @b: a value to compare with. -+ * @Returns: negative value if @a < @b; zero if @a = @b; positive -+ * value if @a > @b. -+ * -+ * Specifies the type of a comparison function used to compare two -+ * values. The function should return a negative integer if the first -+ * value comes before the second, 0 if they are equal, or a positive -+ * integer if the first value comes after the second. -+ **/ -+GList * -+g_list_sort (GList *list, -+ GCompareFunc compare_func) -+{ -+ return g_list_sort_real (list, (GFunc) compare_func, NULL); -+ -+} -+ -+/** -+ * g_list_length: -+ * @list: a #GList -+ * -+ * Gets the number of elements in a #GList. -+ * -+ * -+ * This function iterates over the whole list to -+ * count its elements. -+ * -+ * -+ * Returns: the number of elements in the #GList -+ */ -+guint -+g_list_length (GList *list) -+{ -+ guint length; -+ -+ length = 0; -+ while (list) -+ { -+ length++; -+ list = list->next; -+ } -+ -+ return length; -+} -+ -+/** -+ * g_list_foreach: -+ * @list: a #GList -+ * @func: the function to call with each element's data -+ * @user_data: user data to pass to the function -+ * -+ * Calls a function for each element of a #GList. -+ */ -+/** -+ * GFunc: -+ * @data: the element's data. -+ * @user_data: user data passed to g_list_foreach() or -+ * g_slist_foreach(). -+ * -+ * Specifies the type of functions passed to g_list_foreach() and -+ * g_slist_foreach(). -+ **/ -+void -+g_list_foreach (GList *list, -+ GFunc func, -+ gpointer user_data) -+{ -+ while (list) -+ { -+ GList *next = list->next; -+ (*func) (list->data, user_data); -+ list = next; -+ } -+} -+ -+/** -+ * g_list_free_full: -+ * @list: a pointer to a #GList -+ * @free_func: the function to be called to free each element's data -+ * -+ * Convenience method, which frees all the memory used by a #GList, and -+ * calls the specified destroy function on every element's data. -+ * -+ * Since: 2.28 -+ */ -+void -+g_list_free_full (GList *list, -+ GDestroyNotify free_func) -+{ -+ g_list_foreach (list, (GFunc) free_func, NULL); -+ g_list_free (list); -+} -+ -+/** -+ * g_list_find_custom: -+ * @list: a #GList -+ * @data: user data passed to the function -+ * @func: the function to call for each element. -+ * It should return 0 when the desired element is found -+ * -+ * Finds an element in a #GList, using a supplied function to -+ * find the desired element. It iterates over the list, calling -+ * the given function which should return 0 when the desired -+ * element is found. The function takes two #gconstpointer arguments, -+ * the #GList element's data as the first argument and the -+ * given user data. -+ * -+ * Returns: the found #GList element, or %NULL if it is not found -+ */ -+GList* -+g_list_find_custom (GList *list, -+ gconstpointer data, -+ GCompareFunc func) -+{ -+ g_return_val_if_fail (func != NULL, list); -+ -+ while (list) -+ { -+ if (! func (list->data, data)) -+ return list; -+ list = list->next; -+ } -+ -+ return NULL; -+} -diff --git a/glib-local/glist.h b/glib-local/glist.h -new file mode 100644 -index 0000000..47f2cfe ---- /dev/null -+++ b/glib-local/glist.h -@@ -0,0 +1,56 @@ -+#ifndef __G_LIST_H__ -+#define __G_LIST_H__ -+ -+typedef int gint; -+typedef unsigned int guint; -+typedef void* gpointer; -+typedef const void *gconstpointer; -+typedef gint (*GCompareFunc) (gconstpointer a, -+ gconstpointer b); -+typedef gint (*GCompareDataFunc) (gconstpointer a, -+ gconstpointer b, -+ gpointer user_data); -+typedef void (*GFunc) (gpointer data, -+ gpointer user_data); -+typedef void (*GDestroyNotify) (gpointer data); -+ -+struct _GList; -+typedef struct _GList GList; -+ -+struct _GList -+{ -+ gpointer data; -+ GList *next; -+ GList *prev; -+}; -+ -+/* Doubly linked lists -+ */ -+void g_list_free (GList *list); -+GList* g_list_append (GList *list, -+ gpointer data); -+GList* g_list_delete_link (GList *list, -+ GList *link_); -+GList* g_list_first (GList *list); -+GList* g_list_sort (GList *list, -+ GCompareFunc compare_func); -+guint g_list_length (GList *list); -+void g_list_foreach (GList *list, -+ GFunc func, -+ gpointer user_data); -+void g_list_free_full (GList *list, -+ GDestroyNotify free_func); -+GList* g_list_find_custom (GList *list, -+ gconstpointer data, -+ GCompareFunc func); -+ -+#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL) -+#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL) -+ -+#define g_return_val_if_fail(expr,val) do { \ -+ if (expr) { } else \ -+ { \ -+ return (val); \ -+ } } while(0); -+ -+#endif /* __G_LIST_H__ */ -diff --git a/irqbalance.1 b/irqbalance.1 -index 55fc15f..20105bc 100644 ---- a/irqbalance.1 -+++ b/irqbalance.1 -@@ -39,7 +39,11 @@ Causes irqbalance to be run once, after which the daemon exits - .TP - - .B --debug --Causes irqbalance to run in the foreground and extra debug information to be printed -+Causes irqbalance to print extra debug information. Implies --foreground -+ -+.TP -+.B --foreground -+Causes irqbalance to run in the foreground (without --debug) - - .TP - .B --hintpolicy=[exact | subset | ignore] -@@ -62,6 +66,30 @@ average cpu softirq workload, and no cpus are more than 1 standard deviation - above (and have more than 1 irq assigned to them), attempt to place 1 cpu in - powersave mode. In powersave mode, a cpu will not have any irqs balanced to it, - in an effort to prevent that cpu from waking up without need. -+ -+.TP -+.B --banirq= -+Add the specified irq list to the set of banned irqs. irqbalance will not affect -+the affinity of any irqs on the banned list, allowing them to be specified -+manually. This option is addative and can be specified multiple times -+ -+.TP -+.B --banscript=