[v2,1/2] powerpc/xmon: Paged output for paca display
Michael Ellerman
mpe at ellerman.id.au
Tue Oct 6 22:05:38 AEDT 2015
On Fri, 2015-21-08 at 04:24:27 UTC, Sam bobroff wrote:
> The paca display is already more than 24 lines, which can be problematic
> if you have an old school 80x24 terminal, or more likely you are on a
> virtual terminal which does not scroll for whatever reason.
>
> This patch adds a new command ".", which takes a single (hex) numeric
> argument: lines per page. It will cause the output of "dp" and "dpa"
> to be broken into pages, if necessary.
>
> This is implemented by running over the entire output both for the
> initial command and for each subsequent page: the visible part is
> clipped out by checking line numbers. This is a simplistic approach
> but minimally invasive; it is intended to be easily reusable for other
> commands.
>
> Sample output:
>
> 0:mon> .10
> 0:mon> dp1
> paca for cpu 0x1 @ c00000000fdc0480:
> possible = yes
> present = yes
> online = yes
> lock_token = 0x8000 (0x8)
> paca_index = 0x1 (0xa)
> kernel_toc = 0xc000000000eb2400 (0x10)
> kernelbase = 0xc000000000000000 (0x18)
> kernel_msr = 0xb000000000001032 (0x20)
> emergency_sp = 0xc00000003ffe8000 (0x28)
> mc_emergency_sp = 0xc00000003ffe4000 (0x2e0)
> in_mce = 0x0 (0x2e8)
> data_offset = 0x7f170000 (0x30)
> hw_cpu_id = 0x8 (0x38)
> cpu_start = 0x1 (0x3a)
> kexec_state = 0x0 (0x3b)
> [Enter for next page]
> 0:mon>
> __current = 0xc00000007e696620 (0x290)
> kstack = 0xc00000007e6ebe30 (0x298)
> stab_rr = 0xb (0x2a0)
> saved_r1 = 0xc00000007ef37860 (0x2a8)
> trap_save = 0x0 (0x2b8)
> soft_enabled = 0x0 (0x2ba)
> irq_happened = 0x1 (0x2bb)
> io_sync = 0x0 (0x2bc)
> irq_work_pending = 0x0 (0x2bd)
> nap_state_lost = 0x0 (0x2be)
> 0:mon>
>
> (Based on a similar patch by Michael Ellerman <mpe at ellerman.id.au>
> "[v2] powerpc/xmon: Allow limiting the size of the paca display".
> This patch is an alternative and cannot coexist with the original.)
>
> Signed-off-by: Sam Bobroff <sam.bobroff at au1.ibm.com>
> ---
> arch/powerpc/xmon/xmon.c | 86 +++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 71 insertions(+), 15 deletions(-)
>
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index e599259..9ce9e7d 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -72,6 +72,12 @@ static int xmon_gate;
>
> static unsigned long in_xmon __read_mostly = 0;
>
> +#define XMON_PRINTF(...) do { if (paged_vis()) printf(__VA_ARGS__); } while (0)
Can you do this is a proper function. I know it will need to be varargs, but
that shouldn't be too ugly.
> +#define MAX_PAGED_SIZE 1024
Why do we need a max at all?
> +static unsigned long paged_size = 0, paged_pos, paged_cur_page;
> +#ifdef CONFIG_PPC64
> +static unsigned long paca_cpu;
> +#endif
That can just be static in dump_pacas() by the looks.
> static unsigned long adrs;
> static int size = 1;
> #define MAX_DUMP (128 * 1024)
> @@ -242,6 +248,9 @@ Commands:\n\
> " u dump TLB\n"
> #endif
> " ? help\n"
> +#ifdef CONFIG_PPC64
> +" .# limit output to # lines per page (dump paca only)\n"
> +#endif
Don't make it 64-bit only.
> " zr reboot\n\
> zh halt\n"
> ;
> @@ -833,6 +842,19 @@ static void remove_cpu_bpts(void)
> write_ciabr(0);
> }
>
> +static void paged_set_size(void)
"paged" isn't reading very well for me. Can we use "pagination" instead? I know
it's longer but monitors are wide these days.
Also I prefer verb first usually, so set_pagination_size() etc.
> +{
> + if (!scanhex(&paged_size) || (paged_size > MAX_PAGED_SIZE)) {
> + printf("Invalid number of lines per page (max: %d).\n",
> + MAX_PAGED_SIZE);
> + paged_size = 0;
> + }
> +}
> +static void paged_reset(void)
> +{
> + paged_cur_page = 0;
> +}
You only call that once so a function seems like over kill.
> /* Command interpreting routine */
> static char *last_cmd;
>
> @@ -863,7 +885,8 @@ cmds(struct pt_regs *excp)
> take_input(last_cmd);
> last_cmd = NULL;
> cmd = inchar();
> - }
> + } else
> + paged_reset();
> switch (cmd) {
> case 'm':
> cmd = inchar();
> @@ -924,6 +947,9 @@ cmds(struct pt_regs *excp)
> case '?':
> xmon_puts(help_string);
> break;
> + case '.':
> + paged_set_size();
> + break;
> case 'b':
> bpt_cmds();
> break;
> @@ -2069,6 +2095,31 @@ static void xmon_rawdump (unsigned long adrs, long ndump)
> printf("\n");
> }
>
> +static void paged_start(void)
> +{
> + paged_pos = 0;
> +}
> +
> +static void paged_end(char *next_cmd)
> +{
> + unsigned long next_page_start = ++paged_cur_page * paged_size;
> +
> + if (paged_size && (paged_pos > next_page_start)) {
> + last_cmd = next_cmd;
> + printf("[Enter for next page]\n");
> + }
> +}
> +
> +static bool paged_vis(void)
> +{
> + bool rv = (!paged_size
> + || ((paged_pos >= (paged_size * paged_cur_page))
> + && (paged_pos < (paged_size * (paged_cur_page + 1)))));
Erm.
> +
> + paged_pos++;
> + return rv;
> +}
> +
> #ifdef CONFIG_PPC64
> static void dump_one_paca(int cpu)
> {
> @@ -2084,15 +2135,17 @@ static void dump_one_paca(int cpu)
>
> p = &paca[cpu];
>
> - printf("paca for cpu 0x%x @ %p:\n", cpu, p);
> + XMON_PRINTF("paca for cpu 0x%x @ %p:\n", cpu, p);
>
> - printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
> - printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
> - printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
> + XMON_PRINTF(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
> + XMON_PRINTF(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
> + XMON_PRINTF(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
>
> -#define DUMP(paca, name, format) \
> - printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
> - offsetof(struct paca_struct, name));
> +#define DUMP(paca, name, format) do { \
> + if (paged_vis()) \
> + printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, \
> + paca->name, offsetof(struct paca_struct, name)); \
> +} while (0)
>
> DUMP(p, lock_token, "x");
> DUMP(p, paca_index, "x");
> @@ -2134,13 +2187,14 @@ static void dump_all_pacas(void)
> return;
> }
>
> + paged_start();
> for_each_possible_cpu(cpu)
> dump_one_paca(cpu);
> + paged_end("dpa\n");
> }
>
> static void dump_pacas(void)
> {
> - unsigned long num;
> int c;
>
> c = inchar();
> @@ -2148,13 +2202,15 @@ static void dump_pacas(void)
> dump_all_pacas();
> return;
> }
> + if (c != '_') {
What's that about?
> + termch = c;
> + if (!scanhex(&paca_cpu))
> + paca_cpu = xmon_owner;
> + }
>
> - termch = c; /* Put c back, it wasn't 'a' */
> -
> - if (scanhex(&num))
> - dump_one_paca(num);
> - else
> - dump_one_paca(xmon_owner);
> + paged_start();
> + dump_one_paca(paca_cpu);
> + paged_end("dp_\n");
> }
> #endif
cheers
More information about the Linuxppc-dev
mailing list