From b6fcb602ce0f80e818004340e6ddb5a788bb832d Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sun, 5 Jan 2014 00:00:00 -0600 Subject: [PATCH] top: provide for discontinuous (not active) NUMA nodes Apparently there are occasions when NUMA nodes may not always be contiguous. Under such conditions nodes that were not used would still occupy precious Summary Area space showing 100% idle, under the '2' command toggle. With this commit top will no longer display numa nodes that have no associated cpu when the '2' toggle is on. But just in case we wish to return to former behavior, a new #define called OFF_NUMASKIP has been introduced. And as an aside, a recent refactor mentioned below set the stage for this patch to be 'self-tuning'. In other words, if an inactive/non-displayed node should become active (if even possible), then top will begin showing such a node automatically with the next screen update. Unfortunately, all inactive nodes now 'suppressed' are still accessible via the '3' command. Those nodes will just be displayed as empty (no associated cpus shown). This is not really a top problem but more of a libnuma and/or user deficiency. The library lacks the means to validate a node id and the user then input a node that was not even shown under a '2' toggle Summary display. ( too bad libnuma does not offer an 'is_node_active' ) ( type function so top could warn a user when such a ) ( discontinuous node was requested using his '3' cmd ) ( sure, top could achieve this objective himself but ) ( that would require making yet another array global ) ( which i'm just not in the mood to do - besides, we ) ( have already made enough concessions to libnuma.so ) Lastly, an existing #define (PRETEND_NUMA) was changed to 'disable' node #1 so as to simulate a discontinuous node. This allows testing of the '2' and '3' commands. Reference(s): http://www.spinics.net/lists/util-linux-ng/msg08671.html . set stage for self tuning commit f12c0d5c6e84f9409ac3a73c066841a8ff5aab0b Signed-off-by: Jim Warner --- top/top.c | 16 +++++++++++++++- top/top.h | 8 ++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/top/top.c b/top/top.c index bb15d015..cb1a063b 100644 --- a/top/top.c +++ b/top/top.c @@ -223,7 +223,11 @@ static void *Libnuma_handle; static int Stderr_save = -1; #if defined(PRETEND_NUMA) || defined(PRETEND8CPUS) static int Numa_max_node(void) { return 3; } +#ifndef OFF_NUMASKIP +static int Numa_node_of_cpu(int num) { return (1 == (num % 4)) ? 0 : (num % 4); } +#else static int Numa_node_of_cpu(int num) { return (num % 4); } +#endif #else static int (*Numa_max_node)(void); static int (*Numa_node_of_cpu)(int num); @@ -2430,6 +2434,9 @@ static CPU_t *cpus_refresh (CPU_t *cpus) { nod_ptr->edge = sum_ptr->edge; #endif cpu_ptr->node = node; +#ifndef OFF_NUMASKIP + nod_ptr->id = -1; +#endif } #endif } // end: for each cpu @@ -5056,10 +5063,17 @@ static void summary_show (void) { Msg_row += 1; // display each cpu node's states for (i = 0; i < Numa_node_tot; i++) { + CPU_t *nod_ptr = &smpcpu[1 + smp_num_cpus + i]; if (!isROOM(anyFLG, 1)) break; +#ifndef OFF_NUMASKIP + if (nod_ptr->id) { +#endif snprintf(tmp, sizeof(tmp), N_fmt(NUMA_nodenam_fmt), i); - summary_hlp(&smpcpu[1 + smp_num_cpus + i], tmp); + summary_hlp(nod_ptr, tmp); Msg_row += 1; +#ifndef OFF_NUMASKIP + } +#endif } } else { // display the node summary, then the associated cpus (if room) diff --git a/top/top.h b/top/top.h index 16f7668e..8e83b617 100644 --- a/top/top.h +++ b/top/top.h @@ -41,12 +41,13 @@ //#define INSP_SAVEBUF /* preserve 'Insp_buf' contents in a file */ //#define INSP_SLIDE_1 /* when scrolling left/right don't move 8 */ //#define OFF_HST_HASH /* use BOTH qsort+bsrch vs. hashing scheme */ +//#define OFF_NUMASKIP /* do NOT skip numa nodes if discontinuous */ //#define OFF_SCROLLBK /* disable tty emulators scrollback buffer */ //#define OFF_STDIOLBF /* disable our own stdout _IOFBF override */ //#define PRETEND2_5_X /* pretend we're linux 2.5.x (for IO-wait) */ //#define PRETEND8CPUS /* pretend we're smp with 8 ticsers (sic) */ //#define PRETENDNOCAP /* use a terminal without essential caps */ -//#define PRETEND_NUMA /* pretend we've got some linux NUMA Nodes */ +//#define PRETEND_NUMA /* pretend 4 (or 3 w/o OFF_NUMASKIP) Nodes */ //#define RCFILE_NOERR /* rcfile errs silently default, vs. fatal */ //#define RECALL_FIXED /* don't reorder saved strings if recalled */ //#define RMAN_IGNORED /* don't consider auto right margin glitch */ @@ -277,7 +278,7 @@ typedef struct CPU_t { #ifndef CPU_ZEROTICS SIC_t edge; // tics adjustment threshold boundary #endif - int id; // the cpu id number (0 - nn) + int id; // cpu number (0 - nn), or numa active flag #ifndef NUMA_DISABLE int node; // the numa node it belongs to #endif @@ -628,6 +629,9 @@ typedef struct WIN_t { #if defined(PRETEND_NUMA) && defined(NUMA_DISABLE) # error 'PRETEND_NUMA' confilcts with 'NUMA_DISABLE' #endif +#if defined(OFF_NUMASKIP) && defined(NUMA_DISABLE) +# error 'OFF_NUMASKIP' confilcts with 'NUMA_DISABLE' +#endif #if (LRGBUFSIZ < SCREENMAX) # error 'LRGBUFSIZ' must NOT be less than 'SCREENMAX' #endif