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 branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Martin Schwidefsky:
"Several bug fixes:

- There are four different stack tracers, and three of them have
bugs. For 4.5 the bugs are fixed and we prepare a cleanup patch
for the next merge window.

- Three bug fixes for the dasd driver in regard to parallel access
volumes and the new max_dev_sectors block device queue limit

- The irq restore optimization needs a fixup for memcpy_real

- The diagnose trace code has a conflict with lockdep"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/dasd: fix performance drop
s390/maccess: reduce stnsm instructions
s390/diag: avoid lockdep recursion
s390/dasd: fix refcount for PAV reassignment
s390/dasd: prevent incorrect length error under z/VM after PAV changes
s390: fix DAT off memory access, e.g. on kdump
s390/oprofile: fix address range for asynchronous stack
s390/perf_event: fix address range for asynchronous stack
s390/stacktrace: add save_stack_trace_regs()
s390/stacktrace: save full stack traces
s390/stacktrace: add missing end marker
s390/stacktrace: fix address ranges for asynchronous and panic stack
s390/stacktrace: fix save_stack_trace_tsk() for current task

+73 -29
+5 -3
arch/s390/kernel/perf_event.c
··· 260 260 void perf_callchain_kernel(struct perf_callchain_entry *entry, 261 261 struct pt_regs *regs) 262 262 { 263 - unsigned long head; 263 + unsigned long head, frame_size; 264 264 struct stack_frame *head_sf; 265 265 266 266 if (user_mode(regs)) 267 267 return; 268 268 269 + frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); 269 270 head = regs->gprs[15]; 270 271 head_sf = (struct stack_frame *) head; 271 272 ··· 274 273 return; 275 274 276 275 head = head_sf->back_chain; 277 - head = __store_trace(entry, head, S390_lowcore.async_stack - ASYNC_SIZE, 278 - S390_lowcore.async_stack); 276 + head = __store_trace(entry, head, 277 + S390_lowcore.async_stack + frame_size - ASYNC_SIZE, 278 + S390_lowcore.async_stack + frame_size); 279 279 280 280 __store_trace(entry, head, S390_lowcore.thread_info, 281 281 S390_lowcore.thread_info + THREAD_SIZE);
+34 -13
arch/s390/kernel/stacktrace.c
··· 59 59 } 60 60 } 61 61 62 - void save_stack_trace(struct stack_trace *trace) 62 + static void __save_stack_trace(struct stack_trace *trace, unsigned long sp) 63 63 { 64 - register unsigned long sp asm ("15"); 65 - unsigned long orig_sp, new_sp; 64 + unsigned long new_sp, frame_size; 66 65 67 - orig_sp = sp; 68 - new_sp = save_context_stack(trace, orig_sp, 69 - S390_lowcore.panic_stack - PAGE_SIZE, 70 - S390_lowcore.panic_stack, 1); 71 - if (new_sp != orig_sp) 72 - return; 66 + frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); 67 + new_sp = save_context_stack(trace, sp, 68 + S390_lowcore.panic_stack + frame_size - PAGE_SIZE, 69 + S390_lowcore.panic_stack + frame_size, 1); 73 70 new_sp = save_context_stack(trace, new_sp, 74 - S390_lowcore.async_stack - ASYNC_SIZE, 75 - S390_lowcore.async_stack, 1); 76 - if (new_sp != orig_sp) 77 - return; 71 + S390_lowcore.async_stack + frame_size - ASYNC_SIZE, 72 + S390_lowcore.async_stack + frame_size, 1); 78 73 save_context_stack(trace, new_sp, 79 74 S390_lowcore.thread_info, 80 75 S390_lowcore.thread_info + THREAD_SIZE, 1); 76 + } 77 + 78 + void save_stack_trace(struct stack_trace *trace) 79 + { 80 + register unsigned long r15 asm ("15"); 81 + unsigned long sp; 82 + 83 + sp = r15; 84 + __save_stack_trace(trace, sp); 85 + if (trace->nr_entries < trace->max_entries) 86 + trace->entries[trace->nr_entries++] = ULONG_MAX; 81 87 } 82 88 EXPORT_SYMBOL_GPL(save_stack_trace); 83 89 ··· 92 86 unsigned long sp, low, high; 93 87 94 88 sp = tsk->thread.ksp; 89 + if (tsk == current) { 90 + /* Get current stack pointer. */ 91 + asm volatile("la %0,0(15)" : "=a" (sp)); 92 + } 95 93 low = (unsigned long) task_stack_page(tsk); 96 94 high = (unsigned long) task_pt_regs(tsk); 97 95 save_context_stack(trace, sp, low, high, 0); ··· 103 93 trace->entries[trace->nr_entries++] = ULONG_MAX; 104 94 } 105 95 EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 96 + 97 + void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) 98 + { 99 + unsigned long sp; 100 + 101 + sp = kernel_stack_pointer(regs); 102 + __save_stack_trace(trace, sp); 103 + if (trace->nr_entries < trace->max_entries) 104 + trace->entries[trace->nr_entries++] = ULONG_MAX; 105 + } 106 + EXPORT_SYMBOL_GPL(save_stack_trace_regs);
+3
arch/s390/kernel/trace.c
··· 18 18 unsigned long flags; 19 19 unsigned int *depth; 20 20 21 + /* Avoid lockdep recursion. */ 22 + if (IS_ENABLED(CONFIG_LOCKDEP)) 23 + return; 21 24 local_irq_save(flags); 22 25 depth = this_cpu_ptr(&diagnose_trace_depth); 23 26 if (*depth == 0) {
+8 -4
arch/s390/mm/maccess.c
··· 93 93 */ 94 94 int memcpy_real(void *dest, void *src, size_t count) 95 95 { 96 + int irqs_disabled, rc; 96 97 unsigned long flags; 97 - int rc; 98 98 99 99 if (!count) 100 100 return 0; 101 - local_irq_save(flags); 102 - __arch_local_irq_stnsm(0xfbUL); 101 + flags = __arch_local_irq_stnsm(0xf8UL); 102 + irqs_disabled = arch_irqs_disabled_flags(flags); 103 + if (!irqs_disabled) 104 + trace_hardirqs_off(); 103 105 rc = __memcpy_real(dest, src, count); 104 - local_irq_restore(flags); 106 + if (!irqs_disabled) 107 + trace_hardirqs_on(); 108 + __arch_local_irq_ssm(flags); 105 109 return rc; 106 110 } 107 111
+5 -3
arch/s390/oprofile/backtrace.c
··· 54 54 55 55 void s390_backtrace(struct pt_regs * const regs, unsigned int depth) 56 56 { 57 - unsigned long head; 57 + unsigned long head, frame_size; 58 58 struct stack_frame* head_sf; 59 59 60 60 if (user_mode(regs)) 61 61 return; 62 62 63 + frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); 63 64 head = regs->gprs[15]; 64 65 head_sf = (struct stack_frame*)head; 65 66 ··· 69 68 70 69 head = head_sf->back_chain; 71 70 72 - head = __show_trace(&depth, head, S390_lowcore.async_stack - ASYNC_SIZE, 73 - S390_lowcore.async_stack); 71 + head = __show_trace(&depth, head, 72 + S390_lowcore.async_stack + frame_size - ASYNC_SIZE, 73 + S390_lowcore.async_stack + frame_size); 74 74 75 75 __show_trace(&depth, head, S390_lowcore.thread_info, 76 76 S390_lowcore.thread_info + THREAD_SIZE);
+1
drivers/s390/block/dasd.c
··· 3035 3035 max = block->base->discipline->max_blocks << block->s2b_shift; 3036 3036 } 3037 3037 queue_flag_set_unlocked(QUEUE_FLAG_NONROT, block->request_queue); 3038 + block->request_queue->limits.max_dev_sectors = max; 3038 3039 blk_queue_logical_block_size(block->request_queue, 3039 3040 block->bp_block); 3040 3041 blk_queue_max_hw_sectors(block->request_queue, max);
+17 -6
drivers/s390/block/dasd_alias.c
··· 264 264 spin_unlock_irqrestore(&lcu->lock, flags); 265 265 cancel_work_sync(&lcu->suc_data.worker); 266 266 spin_lock_irqsave(&lcu->lock, flags); 267 - if (device == lcu->suc_data.device) 267 + if (device == lcu->suc_data.device) { 268 + dasd_put_device(device); 268 269 lcu->suc_data.device = NULL; 270 + } 269 271 } 270 272 was_pending = 0; 271 273 if (device == lcu->ruac_data.device) { ··· 275 273 was_pending = 1; 276 274 cancel_delayed_work_sync(&lcu->ruac_data.dwork); 277 275 spin_lock_irqsave(&lcu->lock, flags); 278 - if (device == lcu->ruac_data.device) 276 + if (device == lcu->ruac_data.device) { 277 + dasd_put_device(device); 279 278 lcu->ruac_data.device = NULL; 279 + } 280 280 } 281 281 private->lcu = NULL; 282 282 spin_unlock_irqrestore(&lcu->lock, flags); ··· 553 549 if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) { 554 550 DBF_DEV_EVENT(DBF_WARNING, device, "could not update" 555 551 " alias data in lcu (rc = %d), retry later", rc); 556 - schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ); 552 + if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ)) 553 + dasd_put_device(device); 557 554 } else { 555 + dasd_put_device(device); 558 556 lcu->ruac_data.device = NULL; 559 557 lcu->flags &= ~UPDATE_PENDING; 560 558 } ··· 599 593 */ 600 594 if (!usedev) 601 595 return -EINVAL; 596 + dasd_get_device(usedev); 602 597 lcu->ruac_data.device = usedev; 603 - schedule_delayed_work(&lcu->ruac_data.dwork, 0); 598 + if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0)) 599 + dasd_put_device(usedev); 604 600 return 0; 605 601 } 606 602 ··· 731 723 ASCEBC((char *) &cqr->magic, 4); 732 724 ccw = cqr->cpaddr; 733 725 ccw->cmd_code = DASD_ECKD_CCW_RSCK; 734 - ccw->flags = 0 ; 726 + ccw->flags = CCW_FLAG_SLI; 735 727 ccw->count = 16; 736 728 ccw->cda = (__u32)(addr_t) cqr->data; 737 729 ((char *)cqr->data)[0] = reason; ··· 938 930 /* 3. read new alias configuration */ 939 931 _schedule_lcu_update(lcu, device); 940 932 lcu->suc_data.device = NULL; 933 + dasd_put_device(device); 941 934 spin_unlock_irqrestore(&lcu->lock, flags); 942 935 } 943 936 ··· 998 989 } 999 990 lcu->suc_data.reason = reason; 1000 991 lcu->suc_data.device = device; 992 + dasd_get_device(device); 1001 993 spin_unlock(&lcu->lock); 1002 - schedule_work(&lcu->suc_data.worker); 994 + if (!schedule_work(&lcu->suc_data.worker)) 995 + dasd_put_device(device); 1003 996 };