Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge remote-tracking branch 'tglx/x86/urgent' into x86/urgent

Pick up the WCHAN fixes from Thomas.

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+55 -52
+55
arch/x86/kernel/process.c
··· 506 506 return randomize_range(mm->brk, range_end, 0) ? : mm->brk; 507 507 } 508 508 509 + /* 510 + * Called from fs/proc with a reference on @p to find the function 511 + * which called into schedule(). This needs to be done carefully 512 + * because the task might wake up and we might look at a stack 513 + * changing under us. 514 + */ 515 + unsigned long get_wchan(struct task_struct *p) 516 + { 517 + unsigned long start, bottom, top, sp, fp, ip; 518 + int count = 0; 519 + 520 + if (!p || p == current || p->state == TASK_RUNNING) 521 + return 0; 522 + 523 + start = (unsigned long)task_stack_page(p); 524 + if (!start) 525 + return 0; 526 + 527 + /* 528 + * Layout of the stack page: 529 + * 530 + * ----------- topmax = start + THREAD_SIZE - sizeof(unsigned long) 531 + * PADDING 532 + * ----------- top = topmax - TOP_OF_KERNEL_STACK_PADDING 533 + * stack 534 + * ----------- bottom = start + sizeof(thread_info) 535 + * thread_info 536 + * ----------- start 537 + * 538 + * The tasks stack pointer points at the location where the 539 + * framepointer is stored. The data on the stack is: 540 + * ... IP FP ... IP FP 541 + * 542 + * We need to read FP and IP, so we need to adjust the upper 543 + * bound by another unsigned long. 544 + */ 545 + top = start + THREAD_SIZE - TOP_OF_KERNEL_STACK_PADDING; 546 + top -= 2 * sizeof(unsigned long); 547 + bottom = start + sizeof(struct thread_info); 548 + 549 + sp = READ_ONCE(p->thread.sp); 550 + if (sp < bottom || sp > top) 551 + return 0; 552 + 553 + fp = READ_ONCE(*(unsigned long *)sp); 554 + do { 555 + if (fp < bottom || fp > top) 556 + return 0; 557 + ip = READ_ONCE(*(unsigned long *)(fp + sizeof(unsigned long))); 558 + if (!in_sched_functions(ip)) 559 + return ip; 560 + fp = READ_ONCE(*(unsigned long *)fp); 561 + } while (count++ < 16 && p->state != TASK_RUNNING); 562 + return 0; 563 + }
-28
arch/x86/kernel/process_32.c
··· 324 324 325 325 return prev_p; 326 326 } 327 - 328 - #define top_esp (THREAD_SIZE - sizeof(unsigned long)) 329 - #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) 330 - 331 - unsigned long get_wchan(struct task_struct *p) 332 - { 333 - unsigned long bp, sp, ip; 334 - unsigned long stack_page; 335 - int count = 0; 336 - if (!p || p == current || p->state == TASK_RUNNING) 337 - return 0; 338 - stack_page = (unsigned long)task_stack_page(p); 339 - sp = p->thread.sp; 340 - if (!stack_page || sp < stack_page || sp > top_esp+stack_page) 341 - return 0; 342 - /* include/asm-i386/system.h:switch_to() pushes bp last. */ 343 - bp = *(unsigned long *) sp; 344 - do { 345 - if (bp < stack_page || bp > top_ebp+stack_page) 346 - return 0; 347 - ip = *(unsigned long *) (bp+4); 348 - if (!in_sched_functions(ip)) 349 - return ip; 350 - bp = *(unsigned long *) bp; 351 - } while (count++ < 16); 352 - return 0; 353 - } 354 -
-24
arch/x86/kernel/process_64.c
··· 499 499 } 500 500 EXPORT_SYMBOL_GPL(set_personality_ia32); 501 501 502 - unsigned long get_wchan(struct task_struct *p) 503 - { 504 - unsigned long stack; 505 - u64 fp, ip; 506 - int count = 0; 507 - 508 - if (!p || p == current || p->state == TASK_RUNNING) 509 - return 0; 510 - stack = (unsigned long)task_stack_page(p); 511 - if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE) 512 - return 0; 513 - fp = *(u64 *)(p->thread.sp); 514 - do { 515 - if (fp < (unsigned long)stack || 516 - fp >= (unsigned long)stack+THREAD_SIZE) 517 - return 0; 518 - ip = *(u64 *)(fp+8); 519 - if (!in_sched_functions(ip)) 520 - return ip; 521 - fp = *(u64 *)fp; 522 - } while (count++ < 16); 523 - return 0; 524 - } 525 - 526 502 long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) 527 503 { 528 504 int ret = 0;