On 2018-07-07 15:54, Tetsuo Handa wrote:
> On 2018/07/07 20:12, Ingo Molnar wrote:
>>
>> * Tetsuo Handa <[email protected]> wrote:
>>
>>> From: Tetsuo Handa <[email protected]>
>>>
>>> Since syzbot is confused by concurrent printk() messages [1],
>>> this patch changes show_opcodes() to use snprintf().
>>>
>>> When we start adding prefix to each line of printk() output,
>>> we will be able to handle concurrent printk() messages.
>>>
>>> [1] https://syzkaller.appspot.com/text?tag=CrashReport&x=139d342c400000
>>
>> Does this change the output?
>>
>> - If yes, could you show the before/after output in the changelog,
>>
>> - If not (i.e. if only the number of printk calls is changed, the output is 
>> the 
>>   same), could you say so in the changelog?
> 
> This patch will not change the output unless multiple threads concurrently
> call printk(). The purpose of this patch is to help parsing kernel messages
> when multiple threads are concurrently calling printk() for multiple times
> (e.g. backtrace) by reducing pr_cont()/KERN_CONT usage.
> 
>>
>> Also, 3*OPCODE_BUFSIZE+2+1 is 195 bytes - isn't that a bit too much on-stack 
>> footprint?
> 
> Then, we can reduce it by OPCODE_BUFSIZE bytes by unionizing opcodes[] and 
> buf[].

Why not this instead? Less stack use, less code, no intermediary
snprintfs, no pr_cont...

diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 666a284116ac..c881e8a757d9 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -93,26 +93,16 @@ static void printk_stack_address(unsigned long
address, int reliable,
  */
 void show_opcodes(u8 *rip, const char *loglvl)
 {
-       unsigned int code_prologue = OPCODE_BUFSIZE * 2 / 3;
+       unsigned int prologue = OPCODE_BUFSIZE * 2 / 3;
        u8 opcodes[OPCODE_BUFSIZE];
-       u8 *ip;
-       int i;

-       printk("%sCode: ", loglvl);
-
-       ip = (u8 *)rip - code_prologue;
-       if (probe_kernel_read(opcodes, ip, OPCODE_BUFSIZE)) {
-               pr_cont("Bad RIP value.\n");
+       if (probe_kernel_read(opcodes, rip - prologue, OPCODE_BUFSIZE)) {
+               printk("%sCode: Bad RIP value.\n", loglvl);
                return;
        }
-
-       for (i = 0; i < OPCODE_BUFSIZE; i++, ip++) {
-               if (ip == rip)
-                       pr_cont("<%02x> ", opcodes[i]);
-               else
-                       pr_cont("%02x ", opcodes[i]);
-       }
-       pr_cont("\n");
+       printk("%sCode: %*ph <%02x> %*ph\n", loglvl,
+              prologue, &opcodes[0], opcodes[prologue],
+              OPCODE_BUFSIZE - prologue - 1, &opcodes[prologue + 1]);
 }

 void show_ip(struct pt_regs *regs, const char *loglvl)

Not compile-tested, probably whitespace-damaged, but you get the idea.

Rasmus

Reply via email to