Commit 84a0bd5b2830722cf80ff6ad33ef98101a947e14

Authored by Jason Wessel
1 parent a9fa20a7af

gdbstub: Optimize kgdb's "thread:" response for the gdb serial protocol

The gdb debugger understands how to parse short versions of the thread
reference string as long as the bytes are paired in sets of two
characters.  The kgdb implementation was always sending 8 leading
zeros which could be omitted, and further optimized in the case of
non-negative thread numbers.  The negative numbers are used to
reference a specific cpu in the case of kgdb.

An example of the previous i386 stop packet looks like:
    T05thread:00000000000003bb;

New stop packet response:
    T05thread:03bb;

The previous ThreadInfo response looks like:
    m00000000fffffffe,0000000000000001,0000000000000002,0000000000000003,0000000000000004,0000000000000005,0000000000000006,0000000000000007,000000000000000c,0000000000000088,000000000000008a,000000000000008b,000000000000008c,000000000000008d,000000000000008e,00000000000000d4,00000000000000d5,00000000000000dd

New ThreadInfo response:
    mfffffffe,01,02,03,04,05,06,07,0c,88,8a,8b,8c,8d,8e,d4,d5,dd

A few bytes saved means better response time when using kgdb over a
serial line.

Signed-off-by: Jason Wessel <jason.wessel@windriver.com>

Showing 1 changed file with 19 additions and 18 deletions Side-by-side Diff

kernel/debug/gdbstub.c
... ... @@ -367,28 +367,31 @@
367 367 * remapped to negative TIDs.
368 368 */
369 369  
370   -#define BUF_THREAD_ID_SIZE 16
  370 +#define BUF_THREAD_ID_SIZE 8
371 371  
372 372 static char *pack_threadid(char *pkt, unsigned char *id)
373 373 {
374   - char *limit;
  374 + unsigned char *limit;
  375 + int lzero = 1;
375 376  
376   - limit = pkt + BUF_THREAD_ID_SIZE;
377   - while (pkt < limit)
378   - pkt = pack_hex_byte(pkt, *id++);
  377 + limit = id + (BUF_THREAD_ID_SIZE / 2);
  378 + while (id < limit) {
  379 + if (!lzero || *id != 0) {
  380 + pkt = pack_hex_byte(pkt, *id);
  381 + lzero = 0;
  382 + }
  383 + id++;
  384 + }
379 385  
  386 + if (lzero)
  387 + pkt = pack_hex_byte(pkt, 0);
  388 +
380 389 return pkt;
381 390 }
382 391  
383 392 static void int_to_threadref(unsigned char *id, int value)
384 393 {
385   - unsigned char *scan;
386   - int i = 4;
387   -
388   - scan = (unsigned char *)id;
389   - while (i--)
390   - *scan++ = 0;
391   - put_unaligned_be32(value, scan);
  394 + put_unaligned_be32(value, id);
392 395 }
393 396  
394 397 static struct task_struct *getthread(struct pt_regs *regs, int tid)
... ... @@ -601,7 +604,7 @@
601 604 {
602 605 struct task_struct *g;
603 606 struct task_struct *p;
604   - unsigned char thref[8];
  607 + unsigned char thref[BUF_THREAD_ID_SIZE];
605 608 char *ptr;
606 609 int i;
607 610 int cpu;
... ... @@ -621,8 +624,7 @@
621 624 for_each_online_cpu(cpu) {
622 625 ks->thr_query = 0;
623 626 int_to_threadref(thref, -cpu - 2);
624   - pack_threadid(ptr, thref);
625   - ptr += BUF_THREAD_ID_SIZE;
  627 + ptr = pack_threadid(ptr, thref);
626 628 *(ptr++) = ',';
627 629 i++;
628 630 }
... ... @@ -631,8 +633,7 @@
631 633 do_each_thread(g, p) {
632 634 if (i >= ks->thr_query && !finished) {
633 635 int_to_threadref(thref, p->pid);
634   - pack_threadid(ptr, thref);
635   - ptr += BUF_THREAD_ID_SIZE;
  636 + ptr = pack_threadid(ptr, thref);
636 637 *(ptr++) = ',';
637 638 ks->thr_query++;
638 639 if (ks->thr_query % KGDB_MAX_THREAD_QUERY == 0)
... ... @@ -851,7 +852,7 @@
851 852 memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
852 853  
853 854 if (kgdb_connected) {
854   - unsigned char thref[8];
  855 + unsigned char thref[BUF_THREAD_ID_SIZE];
855 856 char *ptr;
856 857  
857 858 /* Reply to host that an exception has occurred */