Merge pull request #222 from liuchao173/master

irqbalance-ui: support scroll under tui mode of irqbalance-ui
This commit is contained in:
liuchao173 2022-07-05 09:06:33 +08:00 committed by GitHub
commit d558be31ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 262 additions and 70 deletions

View file

@ -89,6 +89,7 @@ gpointer copy_cpu_ban(gconstpointer src, gpointer data __attribute__((unused)))
cpu_ban_t *new = malloc(sizeof(cpu_ban_t)); cpu_ban_t *new = malloc(sizeof(cpu_ban_t));
new->number = old->number; new->number = old->number;
new->is_banned = old->is_banned; new->is_banned = old->is_banned;
new->is_changed = 0;
return new; return new;
} }
@ -100,6 +101,7 @@ gpointer copy_irq(gconstpointer src, gpointer data __attribute__((unused)))
new->load = old->load; new->load = old->load;
new->diff = old->diff; new->diff = old->diff;
new->is_banned = old->is_banned; new->is_banned = old->is_banned;
new->is_changed = 0;
new->class = old->class; new->class = old->class;
new->assigned_to = g_list_copy(old->assigned_to); new->assigned_to = g_list_copy(old->assigned_to);
return new; return new;

View file

@ -371,48 +371,116 @@ gboolean rescan_tree(gpointer data __attribute__((unused)))
free(irqbalance_data); free(irqbalance_data);
return TRUE; return TRUE;
} }
void scroll_window() {
gboolean key_loop(gpointer data __attribute__((unused))) switch(state) {
{ case STATE_TREE:
int c = getch(); display_tree();
switch(c) {
case 'q':
close_window(0);
break; break;
case KEY_F(3): case STATE_SETTINGS:
if (state == STATE_SETTINGS || state == STATE_SETUP_IRQS) {
state = STATE_TREE;
display_tree();
}
break;
case KEY_F(4):
if (state == STATE_TREE || state == STATE_SETUP_IRQS) {
state = STATE_SETTINGS;
settings();
}
settings(); settings();
break; break;
case KEY_F(5): case STATE_SETUP_IRQS:
if (state == STATE_TREE || state == STATE_SETTINGS) { setup_irqs();
state = STATE_SETUP_IRQS;
setup_irqs();
}
break;
case 'c':
if (state == STATE_SETTINGS)
handle_cpu_banning();
break;
case 'i':
if (state == STATE_SETUP_IRQS)
handle_irq_banning();
break;
case 's':
if (state == STATE_SETTINGS)
handle_sleep_setting();
break; break;
default: default:
break; break;
} }
}
gboolean key_loop(gpointer data __attribute__((unused)))
{
while(1) {
int c = getch();
switch(c) {
case 'q':
close_window(0);
break;
case KEY_UP:
if (offset > 0) {
offset--;
scroll_window();
}
break;
case KEY_DOWN:
if (offset < max_offset) {
offset++;
scroll_window();
}
break;
case KEY_NPAGE:
switch (state) {
case STATE_TREE:
offset += LINES - 5;
break;
case STATE_SETTINGS:
offset += LINES - 8;
break;
case STATE_SETUP_IRQS:
offset += LINES - 6;
break;
default:
break;
}
if (offset > max_offset)
offset = max_offset;
scroll_window();
break;
case KEY_PPAGE:
switch (state) {
case STATE_TREE:
offset -= LINES - 5;
break;
case STATE_SETTINGS:
offset -= LINES - 8;
break;
case STATE_SETUP_IRQS:
offset -= LINES - 6;
break;
default:
break;
}
if (offset < 0)
offset = 0;
scroll_window();
break;
case KEY_F(3):
if (state == STATE_SETTINGS || state == STATE_SETUP_IRQS) {
state = STATE_TREE;
offset = 0;
display_tree();
}
break;
case KEY_F(4):
if (state == STATE_TREE || state == STATE_SETUP_IRQS) {
state = STATE_SETTINGS;
offset = 0;
settings();
}
settings();
break;
case KEY_F(5):
if (state == STATE_TREE || state == STATE_SETTINGS) {
state = STATE_SETUP_IRQS;
offset = 0;
setup_irqs();
}
break;
case 'c':
if (state == STATE_SETTINGS)
handle_cpu_banning();
break;
case 'i':
if (state == STATE_SETUP_IRQS)
handle_irq_banning();
break;
case 's':
if (state == STATE_SETTINGS)
handle_sleep_setting();
break;
default:
break;
}
}
return TRUE; return TRUE;
} }

View file

@ -41,6 +41,7 @@ typedef struct irq {
uint64_t load; uint64_t load;
uint64_t diff; uint64_t diff;
char is_banned; char is_banned;
char is_changed;
GList *assigned_to; GList *assigned_to;
int class; int class;
} irq_t; } irq_t;
@ -60,6 +61,7 @@ typedef struct cpu_node {
typedef struct cpu_ban { typedef struct cpu_ban {
int number; int number;
char is_banned; char is_banned;
char is_changed;
} cpu_ban_t; } cpu_ban_t;
typedef struct setup { typedef struct setup {

187
ui/ui.c
View file

@ -3,6 +3,8 @@
#include <string.h> #include <string.h>
#include "ui.h" #include "ui.h"
int offset;
int max_offset;
GList *all_cpus = NULL; GList *all_cpus = NULL;
GList *all_irqs = NULL; GList *all_irqs = NULL;
@ -134,32 +136,54 @@ void get_banned_cpu(int *cpu, void *data __attribute__((unused)))
all_cpus = g_list_append(all_cpus, new); all_cpus = g_list_append(all_cpus, new);
} }
void print_cpu_line(cpu_ban_t *cpu, void *data) void print_tmp_cpu_line(cpu_ban_t *cpu, void *data __attribute__((unused)))
{ {
int *line_offset = data; int line = max_offset - offset + 6;
if(cpu->is_banned) { if (max_offset >= offset && line < LINES - 3) {
attrset(COLOR_PAIR(10)); if (cpu->is_changed)
} else { attrset(COLOR_PAIR(3));
attrset(COLOR_PAIR(9)); else if(cpu->is_banned)
attrset(COLOR_PAIR(10));
else
attrset(COLOR_PAIR(9));
mvprintw(line, 3, "CPU %d ", cpu->number);
mvprintw(line, 19, "%s", cpu->is_banned ?
"YES " :
"NO ");
} }
mvprintw(*line_offset, 3, "CPU %d", cpu->number); max_offset++;
mvprintw(*line_offset, 19, "%s", cpu->is_banned ? }
"YES " :
"NO "); void print_cpu_line(cpu_ban_t *cpu, void *data __attribute__((unused)))
(*line_offset)++; {
int line = max_offset - offset + 6;
if (max_offset >= offset && line < LINES - 2) {
if(cpu->is_banned)
attrset(COLOR_PAIR(10));
else
attrset(COLOR_PAIR(9));
mvprintw(line, 3, "CPU %d ", cpu->number);
mvprintw(line, 19, "%s", cpu->is_banned ?
"YES " :
"NO ");
}
max_offset++;
} }
void print_all_cpus() void print_all_cpus()
{ {
max_offset = 0;
if(all_cpus == NULL) { if(all_cpus == NULL) {
for_each_node(tree, get_cpu, NULL); for_each_node(tree, get_cpu, NULL);
for_each_int(setup.banned_cpus, get_banned_cpu, NULL); for_each_int(setup.banned_cpus, get_banned_cpu, NULL);
all_cpus = g_list_sort(all_cpus, sort_all_cpus); all_cpus = g_list_sort(all_cpus, sort_all_cpus);
} }
int line = 6;
attrset(COLOR_PAIR(2)); attrset(COLOR_PAIR(2));
mvprintw(4, 3, "NUMBER IS BANNED"); mvprintw(4, 3, "NUMBER IS BANNED");
for_each_cpu(all_cpus, print_cpu_line, &line); for_each_cpu(all_cpus, print_cpu_line, NULL);
max_offset -= LINES - 8;
if (max_offset < 0)
max_offset = 0;
} }
void add_banned_cpu(int *banned_cpu, void *data) void add_banned_cpu(int *banned_cpu, void *data)
@ -195,6 +219,7 @@ int toggle_cpu(GList *cpu_list, int cpu_number)
} else { } else {
((cpu_ban_t *)(entry->data))->is_banned = 1; ((cpu_ban_t *)(entry->data))->is_banned = 1;
} }
((cpu_ban_t *)(entry->data))->is_changed = 1;
return ((cpu_ban_t *)(entry->data))->is_banned; return ((cpu_ban_t *)(entry->data))->is_banned;
} }
@ -239,18 +264,37 @@ void handle_cpu_banning()
if(position > 6) { if(position > 6) {
position--; position--;
move(position, 19); move(position, 19);
} else if (offset > 0) {
offset--;
max_offset = 0;
for_each_cpu(tmp, print_tmp_cpu_line, NULL);
max_offset -= LINES - 9;
if (max_offset < 0)
max_offset = 0;
move(position, 19);
} }
break; break;
case KEY_DOWN: case KEY_DOWN:
if(position <= g_list_length(all_cpus) + 4) { if(position < (size_t)(LINES - 4)) {
position++; if (position <= g_list_length(all_cpus) + 4 - offset) {
position++;
move(position, 19);
}
} else if (offset < max_offset) {
offset++;
max_offset = 0;
for_each_cpu(tmp, print_tmp_cpu_line, NULL);
max_offset -= LINES - 9;
if (max_offset < 0)
max_offset = 0;
move(position, 19); move(position, 19);
} }
break; break;
case '\n': case '\n':
case '\r': { case '\r': {
attrset(COLOR_PAIR(3)); attrset(COLOR_PAIR(3));
int banned = toggle_cpu(tmp, position - 6); int banned = toggle_cpu(tmp, position + offset - 6);
mvprintw(position, 3, "CPU %d ", position + offset - 6);
if(banned) { if(banned) {
mvprintw(position, 19, "YES"); mvprintw(position, 19, "YES");
} else { } else {
@ -263,8 +307,7 @@ void handle_cpu_banning()
case 27: case 27:
processing = 0; processing = 0;
curs_set(0); curs_set(0);
/* Forget the changes */ g_list_free(tmp);
tmp = g_list_copy_deep(all_cpus, copy_cpu_ban, NULL);
print_all_cpus(); print_all_cpus();
attrset(COLOR_PAIR(0)); attrset(COLOR_PAIR(0));
mvprintw(LINES - 3, 1, " \ mvprintw(LINES - 3, 1, " \
@ -278,6 +321,7 @@ void handle_cpu_banning()
break; break;
case 's': case 's':
processing = 0; processing = 0;
g_list_free(all_cpus);
all_cpus = tmp; all_cpus = tmp;
curs_set(0); curs_set(0);
print_all_cpus(); print_all_cpus();
@ -324,9 +368,12 @@ void print_assigned_objects_string(irq_t *irq, int *line_offset)
mvprintw(*line_offset, 68, "%s", assigned_to); mvprintw(*line_offset, 68, "%s", assigned_to);
} }
void print_irq_line(irq_t *irq, void *data) void print_tmp_irq_line(irq_t *irq, void *data __attribute__((unused)))
{ {
int *line_offset = data; int line = max_offset - offset + 4;
max_offset++;
if (line < 4 || line >= LINES - 3)
return;
switch(irq->class) { switch(irq->class) {
case(IRQ_OTHER): case(IRQ_OTHER):
attrset(COLOR_PAIR(1)); attrset(COLOR_PAIR(1));
@ -352,23 +399,62 @@ void print_irq_line(irq_t *irq, void *data)
attrset(COLOR_PAIR(0)); attrset(COLOR_PAIR(0));
break; break;
} }
mvprintw(*line_offset, 3, "IRQ %d", irq->vector); mvprintw(line, 3, "IRQ %d ", irq->vector);
mvprintw(*line_offset, 19, "%s", irq->is_banned ? "YES" : "NO "); mvprintw(line, 19, "%s", irq->is_banned ? "YES" : "NO ");
mvprintw(*line_offset, 36, "%s", mvprintw(line, 36, "%s ",
irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]); irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]);
print_assigned_objects_string(irq, line_offset); print_assigned_objects_string(irq, &line);
(*line_offset)++; }
void print_irq_line(irq_t *irq, void *data __attribute__((unused)))
{
int line = max_offset - offset + 4;
max_offset++;
if (line < 4 || line >= LINES - 2)
return;
switch(irq->class) {
case(IRQ_OTHER):
attrset(COLOR_PAIR(1));
break;
case(IRQ_LEGACY):
attrset(COLOR_PAIR(2));
break;
case(IRQ_SCSI):
attrset(COLOR_PAIR(3));
break;
case(IRQ_VIDEO):
attrset(COLOR_PAIR(8));
break;
case(IRQ_ETH):
case(IRQ_GBETH):
case(IRQ_10GBETH):
attrset(COLOR_PAIR(9));
break;
case(IRQ_VIRT_EVENT):
attrset(COLOR_PAIR(10));
break;
default:
attrset(COLOR_PAIR(0));
break;
}
mvprintw(line, 3, "IRQ %d", irq->vector);
mvprintw(line, 19, "%s", irq->is_banned ? "YES" : "NO ");
mvprintw(line, 36, "%s ",
irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]);
print_assigned_objects_string(irq, &line);
} }
void print_all_irqs() void print_all_irqs()
{ {
int line = 4; max_offset = 0;
attrset(COLOR_PAIR(0)); attrset(COLOR_PAIR(0));
mvprintw(2, 3, mvprintw(2, 3,
"NUMBER IS BANNED CLASS \ "NUMBER IS BANNED CLASS \
ASSIGNED TO CPUS"); ASSIGNED TO CPUS");
for_each_irq(all_irqs, print_irq_line, &line); for_each_irq(all_irqs, print_irq_line, NULL);
max_offset -= LINES - 6;
if (max_offset < 0)
max_offset = 0;
} }
int toggle_irq(GList *irq_list, int position) int toggle_irq(GList *irq_list, int position)
@ -384,6 +470,7 @@ int toggle_irq(GList *irq_list, int position)
} else { } else {
((irq_t *)(entry->data))->is_banned = 1; ((irq_t *)(entry->data))->is_banned = 1;
} }
((irq_t *)(entry->data))->is_changed = 1;
return ((irq_t *)(entry->data))->is_banned; return ((irq_t *)(entry->data))->is_banned;
} }
@ -431,18 +518,36 @@ void handle_irq_banning()
if(position > 4) { if(position > 4) {
position--; position--;
move(position, 19); move(position, 19);
} else if (offset > 0) {
offset--;
max_offset = 0;
for_each_irq(tmp, print_tmp_irq_line, NULL);
max_offset -= LINES - 7;
if (max_offset < 0)
max_offset = 0;
move(position, 19);
} }
break; break;
case KEY_DOWN: case KEY_DOWN:
if(position < g_list_length(all_irqs) + 3) { if (position < (size_t)(LINES - 4)) {
position++; if(position < g_list_length(all_irqs) + 3) {
position++;
move(position, 19);
}
} else if (offset < max_offset) {
offset++;
max_offset = 0;
for_each_irq(tmp, print_tmp_irq_line, NULL);
max_offset -= LINES - 7;
if (max_offset < 0)
max_offset = 0;
move(position, 19); move(position, 19);
} }
break; break;
case '\n': case '\n':
case '\r': { case '\r': {
attrset(COLOR_PAIR(3)); attrset(COLOR_PAIR(3));
int banned = toggle_irq(tmp, position - 4); int banned = toggle_irq(tmp, position + offset - 4);
if(banned) { if(banned) {
mvprintw(position, 19, "YES"); mvprintw(position, 19, "YES");
} else { } else {
@ -456,7 +561,7 @@ void handle_irq_banning()
processing = 0; processing = 0;
curs_set(0); curs_set(0);
/* Forget the changes */ /* Forget the changes */
tmp = g_list_copy_deep(all_irqs, copy_irq, NULL); g_list_free(tmp);
print_all_irqs(); print_all_irqs();
attrset(COLOR_PAIR(0)); attrset(COLOR_PAIR(0));
mvprintw(LINES - 3, 1, " \ mvprintw(LINES - 3, 1, " \
@ -470,6 +575,7 @@ void handle_irq_banning()
break; break;
case 's': case 's':
processing = 0; processing = 0;
g_list_free(all_irqs);
all_irqs = tmp; all_irqs = tmp;
curs_set(0); curs_set(0);
print_all_irqs(); print_all_irqs();
@ -548,11 +654,13 @@ void init()
init_pair(10, COLOR_MAGENTA, COLOR_BLACK); init_pair(10, COLOR_MAGENTA, COLOR_BLACK);
} }
offset = 0;
display_tree(); display_tree();
} }
void close_window(int sig __attribute__((unused))) void close_window(int sig __attribute__((unused)))
{ {
g_list_free(all_cpus);
g_list_free(setup.banned_irqs); g_list_free(setup.banned_irqs);
g_list_free(setup.banned_cpus); g_list_free(setup.banned_cpus);
g_list_free_full(tree, free); g_list_free_full(tree, free);
@ -595,10 +703,13 @@ void setup_irqs()
void display_tree_node_irqs(irq_t *irq, void *data) void display_tree_node_irqs(irq_t *irq, void *data)
{ {
char indent[32] = " \0"; char indent[32] = " \0";
snprintf(indent + strlen(indent), 32 - strlen(indent), "%s", (char *)data); if (max_offset >= offset && max_offset - offset < LINES - 5) {
attrset(COLOR_PAIR(3)); snprintf(indent + strlen(indent), 32 - strlen(indent), "%s", (char *)data);
printw("%sIRQ %u, IRQs since last rebalance %lu\n", attrset(COLOR_PAIR(3));
printw("%sIRQ %u, IRQs since last rebalance %lu\n",
indent, irq->vector, irq->diff); indent, irq->vector, irq->diff);
}
max_offset++;
} }
void display_tree_node(cpu_node_t *node, void *data) void display_tree_node(cpu_node_t *node, void *data)
@ -644,7 +755,9 @@ void display_tree_node(cpu_node_t *node, void *data)
default: default:
break; break;
} }
printw("%s", copy_to); if (max_offset >= offset)
printw("%s", copy_to);
max_offset++;
if(g_list_length(node->irqs) > 0) { if(g_list_length(node->irqs) > 0) {
for_each_irq(node->irqs, display_tree_node_irqs, indent); for_each_irq(node->irqs, display_tree_node_irqs, indent);
} }
@ -661,7 +774,11 @@ void display_tree()
char *irqbalance_data = get_data(STATS); char *irqbalance_data = get_data(STATS);
parse_into_tree(irqbalance_data); parse_into_tree(irqbalance_data);
display_banned_cpus(); display_banned_cpus();
max_offset = 0;
for_each_node(tree, display_tree_node, NULL); for_each_node(tree, display_tree_node, NULL);
max_offset -= LINES - 5;
if (max_offset < 0)
max_offset = 0;
show_frame(); show_frame();
show_footer(); show_footer();
refresh(); refresh();

View file

@ -14,6 +14,9 @@
extern GList *tree; extern GList *tree;
extern setup_t setup; extern setup_t setup;
extern int offset;
extern int max_offset;
void show_frame(); void show_frame();
void show_footer(); void show_footer();