2.6.24-rc s390 patch queue
Subsystems (8)
cover 2.6.24-rc s390 patch queue
These are the s390 patches in the queue for 2.6.24-rc. I plan to send a please pull sometime next week. The shortlog:
Christian Borntraeger (2):
[S390] magic sysrq: check for in_atomic before doing an console_unblank [S390] Optimize storage key handling for anonymous pages
Christoph Lameter (1):
[S390] Explicitly code allocpercpu calls in iucv
Heiko Carstens (6):
[S390] Fix irq tracing and lockdep_sys_exit calls. [S390] cmm: remove unused binary sysctls. [S390] appldata: remove unused binary sysctls. [S390] Fix kernel preemption.
[S390] Dont overwrite lowcores on smp_send_stop(). [S390] Fix memory detection.
Peter Oberparleiter (1):
[S390] cio: change device sense procedure to work with pav aliases
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 1/10 cio: change device sense procedure to work with pav aliases
From: Peter Oberparleiter <[email protected]>
Modify the sense id channel program to allow device sensing of pav alias devices which belong to a base device with ungrouped paths.
---
drivers/s390/cio/device_id.c | 45 ++++++++----------------------------------- 1 file changed, 9 insertions(+), 36 deletions(-)
drivers/s390/cio/device_id.c +9 -36
@@ -113,19 +113,10 @@ __ccw_device_sense_id_start(struct ccw_d {struct subchannel *sch;struct ccw1 *ccw; -int ret; sch =to_subchannel (cdev->dev.parent);/* Setup sense channel program. */ ccw = cdev->private->iccws; -if (sch->schib.pmcw.pim !=0x80 ) { -/* more than one path installed. */ - ccw->cmd_code =CCW_CMD_SUSPEND_RECONN ; - ccw->cda =0 ; - ccw->count =0 ; - ccw->flags =CCW_FLAG_SLI |CCW_FLAG_CC ; - ccw++; - } ccw->cmd_code =CCW_CMD_SENSE_ID ; ccw->cda = (__u32 )__pa (&cdev->private->senseid); ccw->count =sizeof (struct senseid );
@@ -133,25 +124,9 @@ __ccw_device_sense_id_start(struct ccw_d/* Reset device status. */ memset (&cdev->private->irb,0 ,sizeof (struct irb )); + cdev->private->flags.intretry =0 ; -/* Try on every path. */ - ret = -ENODEV ; -while (cdev->private->imask !=0 ) { -if ((sch->opm & cdev->private->imask) !=0 && - cdev->private->iretry >0 ) { - cdev->private->iretry--; -/* Reset internal retry indication. */ - cdev->private->flags.intretry =0 ; - ret =cio_start (sch, cdev->private->iccws, - cdev->private->imask); -/* ret is 0, -EBUSY, -EACCES or -ENODEV */ -if (ret != -EACCES ) -return ret; - } - cdev->private->imask >>=1 ; - cdev->private->iretry =5 ; - } -return ret; +return cio_start (sch, ccw,LPM_ANYPATH ); }void
@@ -161,8 +136,7 @@ ccw_device_sense_id_start(struct ccw_devmemset (&cdev->private->senseid,0 ,sizeof (struct senseid )); cdev->private->senseid.cu_type =0xFFFF ; - cdev->private->imask =0x80 ; - cdev->private->iretry =5 ; + cdev->private->iretry =3 ; ret =__ccw_device_sense_id_start (cdev);if (ret && ret != -EBUSY )ccw_device_sense_id_done (cdev, ret);
@@ -278,14 +252,13 @@ ccw_device_sense_id_irq(struct ccw_devicccw_device_sense_id_done (cdev, ret);break ;case -EACCES :/* channel is not operational. */ - sch->lpm &= ~cdev->private->imask; - cdev->private->imask >>=1 ; - cdev->private->iretry =5 ; -/* fall through. */ case -EAGAIN :/* try again. */ - ret =__ccw_device_sense_id_start (cdev); -if (ret ==0 || ret == -EBUSY ) -break ; + cdev->private->iretry--; +if (cdev->private->iretry >0 ) { + ret =__ccw_device_sense_id_start (cdev); +if (ret ==0 || ret == -EBUSY ) +break ; + }/* fall through. */ default :/* Sense ID failed. Try asking VM. */ if (MACHINE_IS_VM ) {
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 2/10 magic sysrq: check for in_atomic before doing an console_unblank
In reply to Martin SchwidefskyFrom: Christian Borntraeger <[email protected]>
When doing an magic sysrq reboot on s390 the following bug message appears:
SysRq : Resetting
BUG: sleeping function called from invalid context at include/asm/semaphore.h:61
in_atomic():1, irqs_disabled():007000000004002a8 000000000fe6bc48 0000000000000002 0000000000000000
000000000fe6bce8 000000000fe6bc60 000000000fe6bc60 000000000012a79a
0000000000000000 07000000004002a8 0000000000000006 0000000000000000
0000000000000000 000000000fe6bc48 000000000000000d 000000000fe6bcb8
00000000004000c8 0000000000103234 000000000fe6bc48 000000000fe6bc90
Call Trace:
(��<00000000001031b2>| show_trace+0x12e/0x148)
��<000000000011ffca>| __might_sleep+0x10a/0x118
��<0000000000129fba>| acquire_console_sem+0x92/0xf4
��<000000000012a2ca>| console_unblank+0xc2/0xc8
��<0000000000107bb4>| machine_restart+0x54/0x6c
��<000000000028e806>| sysrq_handle_reboot+0x26/0x30
��<000000000028e52a>| __handle_sysrq+0xa6/0x180
��<0000000000140134>| run_workqueue+0xcc/0x18c
��<000000000014029a>| worker_thread+0xa6/0x108
��<00000000001458e4>| kthread+0x64/0x9c
��<0000000000106f0e>| kernel_thread_starter+0x6/0xc
��<0000000000106f08>| kernel_thread_starter+0x0/0xcThe only reason for doing a console_unblank on s390 is to flush the log buffer. We have to check for in_atomic before doing a console_unblank as the console is otherwise filled with an unrelated bug message.
---
arch/s390/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kernel/setup.c +1 -1
@@ -347,7 +347,7 @@ void (*_machine_power_off)(void) = do_mavoid machine_restart (char *command) { -if (!in_interrupt () || oops_in_progress) +if ((!in_interrupt () && !in_atomic ()) || oops_in_progress)/* * Only unblank the console if we are called in enabled * context or a bust_spinlocks cleared the way for us.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 3/10 Fix irq tracing and lockdep_sys_exit calls.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Current support for TRACE_IRQFLAGS and lockdep_sys_exit is broken. IRQ flag tracing is broken for program checks. Even worse is that the newly introduced calls to lockdep_sys_exit are in the critical section code which is not supposed to call any C functions. In addition the checks if locks are still held are also done when returning to kernel code which is broken as well.
Fix all this by disabling interrupts and machine checks at the exit paths and then do the appropriate checks and calls.
---
arch/s390/kernel/entry.S | 109 +++++++++++++++++++++++++++++++-------------- arch/s390/kernel/entry64.S | 106 ++++++++++++++++++++++++++++++------------- arch/s390/kernel/setup.c | 4 + include/asm-s390/system.h | 5 ++ 4 files changed, 158 insertions(+), 66 deletions(-)
arch/s390/kernel/entry64.S +73 -33
@@ -67,12 +67,28 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_ brasl %r14,trace_hardirqs_off .endm - .macro LOCKDEP_SYS_EXIT - brasl %r14,lockdep_sys_exit + .macro TRACE_IRQS_CHECK + tm SP_PSW(%r15),0x03 # irqs enabled? + jz 0f + brasl %r14,trace_hardirqs_on + j 1f +0: brasl %r14,trace_hardirqs_off +1: .endm #else #define TRACE_IRQS_ON #define TRACE_IRQS_OFF +#define TRACE_IRQS_CHECK +#endif + +#ifdef CONFIG_LOCKDEP + .macro LOCKDEP_SYS_EXIT + tm SP_PSW+1(%r15),0x01 # returning to user ? + jz 0f + brasl %r14,lockdep_sys_exit +0: + .endm +#else #define LOCKDEP_SYS_EXIT #endif
@@ -222,8 +238,6 @@ sysc_saveall: llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING sysc_vtime: - tm SP_PSW+1(%r15),0x01 # interrupting from user ? - jz sysc_do_svc UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER sysc_stime: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -257,19 +271,34 @@ sysc_noemu: sysc_return: tm SP_PSW+1(%r15),0x01 # returning to user ? - jno sysc_leave + jno sysc_restore tm __TI_flags+7(%r9),_TIF_WORK_SVC jnz sysc_work # there is work to do (signals etc.) +sysc_restore: +#ifdef CONFIG_TRACE_IRQFLAGS + larl %r1,sysc_restore_trace_psw + lpswe 0(%r1) +sysc_restore_trace: + TRACE_IRQS_CHECK LOCKDEP_SYS_EXIT +#endif sysc_leave: RESTORE_ALL __LC_RETURN_PSW,1 +sysc_done: + +#ifdef CONFIG_TRACE_IRQFLAGS + .align 8 + .globl sysc_restore_trace_psw +sysc_restore_trace_psw: + .quad 0, sysc_restore_trace +#endif # # recheck if there is more work to do # sysc_work_loop: tm __TI_flags+7(%r9),_TIF_WORK_SVC - jz sysc_leave # there is no work to do + jz sysc_restore # there is no work to do # # One of the work bits is on. Find out which one. #
@@ -284,8 +313,8 @@ sysc_work: jo sysc_restart tm __TI_flags+7(%r9),_TIF_SINGLE_STEP jo sysc_singlestep - LOCKDEP_SYS_EXIT - j sysc_leave + j sysc_restore +sysc_work_done: # # _TIF_NEED_RESCHED is set, call schedule
@@ -445,6 +474,7 @@ pgm_check_handler: pgm_no_vtime: #endif lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct + TRACE_IRQS_OFF lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f ngr %r8,%r3
@@ -484,6 +514,7 @@ pgm_per_std: pgm_no_vtime2: #endif lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct + TRACE_IRQS_OFF lg %r1,__TI_task(%r9) tm SP_PSW+1(%r15),0x01 # kernel per event ? jz kernel_per
@@ -504,12 +535,9 @@ pgm_svcper: SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING - tm SP_PSW+1(%r15),0x01 # interrupting from user ? - jz pgm_no_vtime3 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER -pgm_no_vtime3: #endif llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
@@ -529,7 +557,7 @@ kernel_per: lhi %r0,__LC_PGM_OLD_PSW sth %r0,SP_TRAP(%r15) # set trap indication to pgm check la %r2,SP_PTREGS(%r15) # address of register-save area - larl %r14,sysc_leave # load adr. of system ret, no work + larl %r14,sysc_restore # load adr. of system ret, no work jg do_single_step # branch to do_single_step /*
@@ -554,26 +582,38 @@ io_no_vtime: TRACE_IRQS_OFF la %r2,SP_PTREGS(%r15) # address of register-save area brasl %r14,do_IRQ # call standard irq handler - TRACE_IRQS_ON - io_return: tm SP_PSW+1(%r15),0x01 # returning to user ? #ifdef CONFIG_PREEMPT jno io_preempt # no -> check for preemptive scheduling #else - jno io_leave # no-> skip resched & signal + jno io_restore # no-> skip resched & signal #endif tm __TI_flags+7(%r9),_TIF_WORK_INT jnz io_work # there is work to do (signals etc.) +io_restore: +#ifdef CONFIG_TRACE_IRQFLAGS + larl %r1,io_restore_trace_psw + lpswe 0(%r1) +io_restore_trace: + TRACE_IRQS_CHECK LOCKDEP_SYS_EXIT +#endif io_leave: RESTORE_ALL __LC_RETURN_PSW,0 io_done: +#ifdef CONFIG_TRACE_IRQFLAGS + .align 8 + .globl io_restore_trace_psw +io_restore_trace_psw: + .quad 0, io_restore_trace +#endif + #ifdef CONFIG_PREEMPT io_preempt: icm %r0,15,__TI_precount(%r9) - jnz io_leave + jnz io_restore # switch to kernel stack lg %r1,SP_R15(%r15) aghi %r1,-SP_SIZE
@@ -582,12 +622,14 @@ io_preempt: lgr %r15,%r1 io_resume_loop: tm __TI_flags+7(%r9),_TIF_NEED_RESCHED - jno io_leave + jno io_restore larl %r1,.Lc_pactive mvc __TI_precount(4,%r9),0(%r1) + TRACE_IRQS_ON stosm __SF_EMPTY(%r15),0x03 # reenable interrupts brasl %r14,schedule # call schedule stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + TRACE_IRQS_OFF xc __TI_precount(4,%r9),__TI_precount(%r9) j io_resume_loop #endif
@@ -613,37 +655,39 @@ io_work_loop: jo io_reschedule tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) jnz io_sigpending - LOCKDEP_SYS_EXIT - j io_leave + j io_restore +io_work_done: # # _TIF_MCCK_PENDING is set, call handler # io_mcck_pending: - TRACE_IRQS_OFF brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler - TRACE_IRQS_ON j io_work_loop # # _TIF_NEED_RESCHED is set, call schedule # io_reschedule: + TRACE_IRQS_ON stosm __SF_EMPTY(%r15),0x03 # reenable interrupts brasl %r14,schedule # call scheduler stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + TRACE_IRQS_OFF tm __TI_flags+7(%r9),_TIF_WORK_INT - jz io_leave # there is no work to do + jz io_restore # there is no work to do j io_work_loop # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # io_sigpending: + TRACE_IRQS_ON stosm __SF_EMPTY(%r15),0x03 # reenable interrupts la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,do_signal # call do_signal stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + TRACE_IRQS_OFF j io_work_loop /*
@@ -669,7 +713,6 @@ ext_no_vtime: la %r2,SP_PTREGS(%r15) # address of register-save area llgh %r3,__LC_EXT_INT_CODE # get interruption code brasl %r14,do_extint - TRACE_IRQS_ON j io_return __critical_end:
@@ -824,15 +867,15 @@ cleanup_table_system_call: cleanup_table_sysc_return: .quad sysc_return, sysc_leave cleanup_table_sysc_leave: - .quad sysc_leave, sysc_work_loop + .quad sysc_leave, sysc_done cleanup_table_sysc_work_loop: - .quad sysc_work_loop, sysc_reschedule + .quad sysc_work_loop, sysc_work_done cleanup_table_io_return: .quad io_return, io_leave cleanup_table_io_leave: .quad io_leave, io_done cleanup_table_io_work_loop: - .quad io_work_loop, io_mcck_pending + .quad io_work_loop, io_work_done cleanup_critical: clc 8(8,%r12),BASED(cleanup_table_system_call)
@@ -901,8 +944,6 @@ cleanup_system_call: cleanup_vtime: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) jhe cleanup_stime - tm SP_PSW+1(%r15),0x01 # interrupting from user ? - jz cleanup_novtime UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER cleanup_stime: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32)
@@ -910,7 +951,6 @@ cleanup_stime: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER cleanup_update: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER -cleanup_novtime: #endif mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) la %r12,__LC_RETURN_PSW
@@ -949,10 +989,10 @@ cleanup_sysc_leave: 2: la %r12,__LC_RETURN_PSW br %r14 cleanup_sysc_leave_insn: + .quad sysc_done - 4 #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .quad sysc_leave + 16 + .quad sysc_done - 8 #endif - .quad sysc_leave + 12 cleanup_io_return: mvc __LC_RETURN_PSW(8),0(%r12)
@@ -979,10 +1019,10 @@ cleanup_io_leave: 2: la %r12,__LC_RETURN_PSW br %r14 cleanup_io_leave_insn: + .quad io_done - 4 #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .quad io_leave + 20 + .quad io_done - 8 #endif - .quad io_leave + 16 /* * Integer constants
arch/s390/kernel/entry.S +76 -33
293 lines not on this page · raw message
arch/s390/kernel/setup.c +4 -0
@@ -492,6 +492,10 @@ static void setup_addressing_mode(void)printk ("S390 address spaces switched, " );set_amode_and_uaccess (PSW_ASC_PRIMARY ,PSW32_ASC_PRIMARY ); } +#ifdef CONFIG_TRACE_IRQFLAGS + sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK ; + io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK ; +#endif } static void __init
include/asm-s390/system.h +5 -0
@@ -388,6 +388,11 @@ extern void (*_machine_power_off)(void);#define arch_align_stack (x) (x) +#ifdef CONFIG_TRACE_IRQFLAGS +extern psw_t sysc_restore_trace_psw; +extern psw_t io_restore_trace_psw; +#endif +#endif /* __KERNEL__ */ #endif
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 4/10 cmm: remove unused binary sysctls.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Remove binary sysctls that never worked due to missing strategy functions.
---
arch/s390/mm/cmm.c | 3 --- include/linux/sysctl.h | 5 ----- kernel/sysctl_check.c | 3 --- 3 files changed, 11 deletions(-)
arch/s390/mm/cmm.c +0 -3
@@ -341,19 +341,16 @@ cmm_timeout_handler(ctl_table *ctl, intstatic struct ctl_table cmm_table[] = { { - .ctl_name =VM_CMM_PAGES , .procname ="cmm_pages" , .mode =0644 , .proc_handler = &cmm_pages_handler, }, { - .ctl_name =VM_CMM_TIMED_PAGES , .procname ="cmm_timed_pages" , .mode =0644 , .proc_handler = &cmm_pages_handler, }, { - .ctl_name =VM_CMM_TIMEOUT , .procname ="cmm_timeout" , .mode =0644 , .proc_handler = &cmm_timeout_handler,
include/linux/sysctl.h +0 -5
@@ -207,11 +207,6 @@ enumVM_PANIC_ON_OOM =33 ,/* panic at out-of-memory */ VM_VDSO_ENABLED =34 ,/* map VDSO into new processes? */ VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */ - -/* s390 vm cmm sysctls */ -VM_CMM_PAGES =1111 , -VM_CMM_TIMED_PAGES =1112 , - VM_CMM_TIMEOUT=1113, };
kernel/sysctl_check.c +0 -3
@@ -140,9 +140,6 @@ static struct trans_ctl_table trans_vm_t { VM_PANIC_ON_OOM, "panic_on_oom" }, { VM_VDSO_ENABLED, "vdso_enabled" }, { VM_MIN_SLAB, "min_slab_ratio" }, - { VM_CMM_PAGES, "cmm_pages" }, - { VM_CMM_TIMED_PAGES, "cmm_timed_pages" }, - { VM_CMM_TIMEOUT, "cmm_timeout" }, {} };
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 5/10 appldata: remove unused binary sysctls.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Remove binary sysctls that never worked due to missing strategy functions.
---
arch/s390/appldata/appldata.h | 1 arch/s390/appldata/appldata_base.c | 74 ++++++---------------------------- arch/s390/appldata/appldata_mem.c | 1 arch/s390/appldata/appldata_net_sum.c | 1 arch/s390/appldata/appldata_os.c | 1 include/linux/sysctl.h | 1 kernel/sysctl_check.c | 11 ----- 7 files changed, 15 insertions(+), 75 deletions(-)
arch/s390/appldata/appldata_base.c +15 -59
@@ -53,29 +53,26 @@ static int appldata_interval_handler(ctlstatic struct ctl_table_header *appldata_sysctl_header;static struct ctl_table appldata_table[] = { { - .ctl_name =CTL_APPLDATA_TIMER , .procname ="timer" , .mode =S_IRUGO |S_IWUSR , .proc_handler = &appldata_timer_handler, }, { - .ctl_name =CTL_APPLDATA_INTERVAL , .procname ="interval" , .mode =S_IRUGO |S_IWUSR , .proc_handler = &appldata_interval_handler, }, - { .ctl_name =0 } + { }, };static struct ctl_table appldata_dir_table[] = { { - .ctl_name =CTL_APPLDATA , .procname = appldata_proc_name, .maxlen =0 , .mode =S_IRUGO |S_IXUGO , .child = appldata_table, }, - { .ctl_name =0 } + { }, };/*
@@ -441,75 +438,38 @@ out:*/ int appldata_register_ops (struct appldata_ops *ops) { -struct list_head *lh; -struct appldata_ops *tmp_ops; -int i; - - i =0 ; +if ((ops->size >APPLDATA_MAX_REC_SIZE ) || (ops->size <0 )) +return -EINVAL ; -if ((ops->size >APPLDATA_MAX_REC_SIZE ) || - (ops->size <0 )){ -P_ERROR ("Invalid size of %s record = %i, maximum = %i!\n" , - ops->name, ops->size,APPLDATA_MAX_REC_SIZE ); -return -ENOMEM ; - } -if ((ops->ctl_nr ==CTL_APPLDATA ) || - (ops->ctl_nr ==CTL_APPLDATA_TIMER ) || - (ops->ctl_nr ==CTL_APPLDATA_INTERVAL )) { -P_ERROR ("ctl_nr %i already in use!\n" , ops->ctl_nr); -return -EBUSY ; - } - ops->ctl_table =kzalloc (4 *sizeof (struct ctl_table ),GFP_KERNEL ); -if (ops->ctl_table ==NULL ) { -P_ERROR ("Not enough memory for %s ctl_table!\n" , ops->name); + ops->ctl_table =kzalloc (4 *sizeof (struct ctl_table ),GFP_KERNEL ); +if (!ops->ctl_table)return -ENOMEM ; - }spin_lock (&appldata_ops_lock); -list_for_each (lh, &appldata_ops_list) { - tmp_ops = list_entry(lh, struct appldata_ops, list); -P_DEBUG ("register_ops loop: %i) name = %s, ctl = %i\n" , - ++i, tmp_ops->name, tmp_ops->ctl_nr); -P_DEBUG ("Comparing %s (ctl %i) with %s (ctl %i)\n" , - tmp_ops->name, tmp_ops->ctl_nr, ops->name, - ops->ctl_nr); -if (strncmp (tmp_ops->name, ops->name, -APPLDATA_PROC_NAME_LENGTH ) ==0 ) { -P_ERROR ("Name \"%s\" already registered!\n" , ops->name); -kfree (ops->ctl_table); -spin_unlock (&appldata_ops_lock); -return -EBUSY ; - } -if (tmp_ops->ctl_nr == ops->ctl_nr) { -P_ERROR ("ctl_nr %i already registered!\n" , ops->ctl_nr); -kfree (ops->ctl_table); -spin_unlock (&appldata_ops_lock); -return -EBUSY ; - } - }list_add (&ops->list, &appldata_ops_list);spin_unlock (&appldata_ops_lock); - ops->ctl_table[0 ].ctl_name =CTL_APPLDATA ; ops->ctl_table[0 ].procname = appldata_proc_name; ops->ctl_table[0 ].maxlen =0 ; ops->ctl_table[0 ].mode =S_IRUGO |S_IXUGO ; ops->ctl_table[0 ].child = &ops->ctl_table[2 ]; - ops->ctl_table[1 ].ctl_name =0 ; - - ops->ctl_table[2 ].ctl_name = ops->ctl_nr; ops->ctl_table[2 ].procname = ops->name; ops->ctl_table[2 ].mode =S_IRUGO |S_IWUSR ; ops->ctl_table[2 ].proc_handler = appldata_generic_handler; ops->ctl_table[2 ].data = ops; - ops->ctl_table[3 ].ctl_name =0 ; - ops->sysctl_header =register_sysctl_table (ops->ctl_table); - +if (!ops->sysctl_header) + goto out;P_INFO ("%s-ops registered!\n" , ops->name);return 0 ; +out: +spin_lock (&appldata_ops_lock); +list_del (&ops->list); +spin_unlock (&appldata_ops_lock); +kfree (ops->ctl_table); +return -ENOMEM ; }/*
@@ -519,15 +479,11 @@ int appldata_register_ops(struct appldat*/ void appldata_unregister_ops (struct appldata_ops *ops) { -void *table;spin_lock (&appldata_ops_lock);list_del (&ops->list); -/* at that point any incoming access will fail */ - table = ops->ctl_table; - ops->ctl_table =NULL ;spin_unlock (&appldata_ops_lock);unregister_sysctl_table (ops->sysctl_header); -kfree (table); +kfree (ops->ctl_table);P_INFO ("%s-ops unregistered!\n" , ops->name); }/********************** module-ops management <END> **************************/
arch/s390/appldata/appldata.h +0 -1
@@ -45,7 +45,6 @@ struct appldata_ops {int active;/* monitoring status */ /* fill in from here */ -unsigned int ctl_nr;/* sysctl ID */ char name[APPLDATA_PROC_NAME_LENGTH ];/* name of /proc fs node */ unsigned char record_nr;/* Record Nr. for Product ID */ void (*callback)(void *data);/* callback function */
arch/s390/appldata/appldata_mem.c +0 -1
@@ -147,7 +147,6 @@ static void appldata_get_mem_data(void *static struct appldata_ops ops = { - .ctl_nr =CTL_APPLDATA_MEM , .name ="mem" , .record_nr =APPLDATA_RECORD_MEM_ID , .size =sizeof (struct appldata_mem_data ),
arch/s390/appldata/appldata_net_sum.c +0 -1
@@ -142,7 +142,6 @@ static void appldata_get_net_sum_data(vostatic struct appldata_ops ops = { - .ctl_nr =CTL_APPLDATA_NET_SUM , .name ="net_sum" , .record_nr =APPLDATA_RECORD_NET_SUM_ID , .size =sizeof (struct appldata_net_sum_data ),
arch/s390/appldata/appldata_os.c +0 -1
@@ -82,7 +82,6 @@ struct appldata_os_data {static struct appldata_os_data *appldata_os_data;static struct appldata_ops ops = { - .ctl_nr =CTL_APPLDATA_OS , .name ="os" , .record_nr =APPLDATA_RECORD_OS_ID , .owner =THIS_MODULE ,
include/linux/sysctl.h +0 -1
@@ -70,7 +70,6 @@ enumCTL_ABI =9 ,/* Binary emulation */ CTL_CPU =10 ,/* CPU stuff (speed scaling, etc) */ CTL_ARLAN =254 ,/* arlan wireless driver */ -CTL_APPLDATA =2120 ,/* s390 appldata */ CTL_S390DBF =5677 ,/* s390 debug */ CTL_SUNRPC =7249 ,/* sunrpc debug */ CTL_PM=9899, /* frv power management */
kernel/sysctl_check.c +0 -11
@@ -1216,16 +1216,6 @@ static struct trans_ctl_table trans_arla {} }; -static struct trans_ctl_table trans_appldata_table[] = { - {CTL_APPLDATA_TIMER ,"timer" }, - {CTL_APPLDATA_INTERVAL ,"interval" }, - {CTL_APPLDATA_OS ,"os" }, - {CTL_APPLDATA_NET_SUM ,"net_sum" }, - {CTL_APPLDATA_MEM ,"mem" }, - {} - -}; -static struct trans_ctl_table trans_s390dbf_table[] = { {5678 /* CTL_S390DBF_STOPPABLE */ ,"debug_stoppable" }, {5679 /* CTL_S390DBF_ACTIVE */ ,"debug_active" },
@@ -1270,7 +1260,6 @@ static struct trans_ctl_table trans_root { CTL_ABI, "abi" },/* CTL_CPU not used */ { CTL_ARLAN, "arlan", trans_arlan_table }, - { CTL_APPLDATA, "appldata", trans_appldata_table }, { CTL_S390DBF, "s390dbf", trans_s390dbf_table }, { CTL_SUNRPC, "sunrpc", trans_sunrpc_table }, { CTL_PM, "pm", trans_pm_table },
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 6/10 Fix kernel preemption.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
When returning from IRQ handling and TIF_NEED_RESCHED is set we must call preempt_schedule_irq() instead of schedule(). Otherwise the BKL might be unlocked in schedule() and therfore everything that relies on the BKL is broken.
---
arch/s390/kernel/entry.S | 15 +++++---------- arch/s390/kernel/entry64.S | 12 ++---------- 2 files changed, 7 insertions(+), 20 deletions(-)
arch/s390/kernel/entry64.S +2 -10
@@ -623,15 +623,8 @@ io_preempt: io_resume_loop: tm __TI_flags+7(%r9),_TIF_NEED_RESCHED jno io_restore - larl %r1,.Lc_pactive - mvc __TI_precount(4,%r9),0(%r1) - TRACE_IRQS_ON - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - brasl %r14,schedule # call schedule - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts - TRACE_IRQS_OFF - xc __TI_precount(4,%r9),__TI_precount(%r9) - j io_resume_loop + larl %r14,io_resume_loop + jg preempt_schedule_irq #endif #
@@ -1029,7 +1022,6 @@ cleanup_io_leave_insn: */ .align 4 .Lconst: -.Lc_pactive: .long PREEMPT_ACTIVE .Lnr_syscalls: .long NR_syscalls .L0x0130: .short 0x130 .L0x0140: .short 0x140
arch/s390/kernel/entry.S +5 -10
@@ -640,15 +640,9 @@ io_preempt: io_resume_loop: tm __TI_flags+3(%r9),_TIF_NEED_RESCHED bno BASED(io_restore) - mvc __TI_precount(4,%r9),BASED(.Lc_pactive) - TRACE_IRQS_ON - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - l %r1,BASED(.Lschedule) - basr %r14,%r1 # call schedule - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts - TRACE_IRQS_OFF - xc __TI_precount(4,%r9),__TI_precount(%r9) - b BASED(io_resume_loop) + l %r1,BASED(.Lpreempt_schedule_irq) + la %r14,BASED(io_resume_loop) + br %r1 # call schedule #endif #
@@ -1062,7 +1056,6 @@ cleanup_io_leave_insn: .align 4 .Lc_spsize: .long SP_SIZE .Lc_overhead: .long STACK_FRAME_OVERHEAD -.Lc_pactive: .long PREEMPT_ACTIVE .Lnr_syscalls: .long NR_syscalls .L0x018: .short 0x018 .L0x020: .short 0x020
@@ -1086,6 +1079,8 @@ cleanup_io_leave_insn: .Lexecve_tail: .long execve_tail .Ljump_table: .long pgm_check_table .Lschedule: .long schedule +.Lpreempt_schedule_irq: + .long preempt_schedule_irq .Ltrace: .long syscall_trace .Lschedtail: .long schedule_tail .Lsysc_table: .long sys_call_table
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 7/10 Optimize storage key handling for anonymous pages
In reply to Martin SchwidefskyFrom: Christian Borntraeger <[email protected]>
page_mkclean used to call page_clear_dirty for every given page. This is different to all other architectures, where the dirty bit in the PTEs is only resetted, if page_mapping() returns a non-NULL pointer. We can move the page_test_dirty/page_clear_dirty sequence into the 2nd if to avoid unnecessary iske/sske sequences, which are expensive.
This change also helps kvm for s390 as the host must transfer the dirty bit into the guest status bits. By moving the page_clear_dirty operation into the 2nd if, the vm will only call page_clear_dirty for pages where it walks the mapping anyway. There it calls ptep_clear_flush for writable ptes, so we can transfer the dirty bit to the guest.
---
mm/rmap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
mm/rmap.c +5 -4
@@ -471,11 +471,12 @@ int page_mkclean(struct page *page)if (page_mapped (page)) {struct address_space *mapping =page_mapping (page); -if (mapping) +if (mapping) { ret =page_mkclean_file (mapping, page); -if (page_test_dirty (page)) { -page_clear_dirty (page); - ret =1 ; +if (page_test_dirty (page)) { +page_clear_dirty (page); + ret =1 ; + } } }
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 8/10 Dont overwrite lowcores on smp_send_stop().
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Don't perform a sigp store-status-at-address on smp_send_stop(). It will overwrite the lowcores of other cpus and destroys valueable debug informations.
---
arch/s390/kernel/smp.c | 56 ++++++------------------------------------------- 1 file changed, 7 insertions(+), 49 deletions(-)
arch/s390/kernel/smp.c +7 -49
@@ -193,72 +193,30 @@ int smp_call_function_single(int cpu, vo }EXPORT_SYMBOL (smp_call_function_single); -static void do_send_stop (void ) +void smp_send_stop (void ) {int cpu, rc; -/* stop all processors */ -for_each_online_cpu (cpu) { -if (cpu ==smp_processor_id ()) -continue ; -do { - rc =signal_processor (cpu, sigp_stop); - }while (rc == sigp_busy); - } -} +/* Disable all interrupts/machine checks */ +__load_psw_mask (psw_kernel_bits & ~PSW_MASK_MCHECK ); -static void do_store_status (void ) -{ -int cpu, rc; +/* write magic number to zero page (absolute 0) */ + lowcore_ptr[smp_processor_id ()]->panic_magic = __PANIC_MAGIC; -/* store status of all processors in their lowcores (real 0) */ +/* stop all processors */ for_each_online_cpu (cpu) {if (cpu ==smp_processor_id ())continue ;do { - rc =signal_processor_p ( - (__u32 )(unsigned long ) lowcore_ptr[cpu], cpu, - sigp_store_status_at_address); + rc =signal_processor (cpu, sigp_stop); }while (rc == sigp_busy); - } -} -static void do_wait_for_stop (void ) -{ -int cpu; - -/* Wait for all other cpus to enter stopped state */ -for_each_online_cpu (cpu) { -if (cpu ==smp_processor_id ()) -continue ;while (!smp_cpu_not_running (cpu))cpu_relax (); } }/* -* this function sends a 'stop' sigp to all other CPUs in the system. -* it goes straight through. -*/ -void smp_send_stop (void ) -{ -/* Disable all interrupts/machine checks */ -__load_psw_mask (psw_kernel_bits & ~PSW_MASK_MCHECK ); - -/* write magic number to zero page (absolute 0) */ - lowcore_ptr[smp_processor_id ()]->panic_magic = __PANIC_MAGIC; - -/* stop other processors. */ -do_send_stop (); - -/* wait until other processors are stopped */ -do_wait_for_stop (); - -/* store status of other processors. */ -do_store_status (); -} - -/* * Reboot, halt and power_off routines for SMP. */ void machine_restart_smp (char *__unused)
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 9/10 Explicitly code allocpercpu calls in iucv
In reply to Martin SchwidefskyFrom: Christoph Lameter <[email protected]>
The iucv is the only user of the various functions that are used to bring parts of cpus up and down. Its the only allocpercpu user that will do I/O on per cpu objects (which is difficult to do with virtually mapped memory). And its the only use of allocpercpu where a GFP_DMA allocation is done.
Remove the allocpercpu calls from iucv and code the allocation and freeing manually. After this patch it is possible to remove a large part of the allocpercpu API.
---
net/iucv/iucv.c | 107 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 46 deletions(-)
net/iucv/iucv.c +61 -46
@@ -97,7 +97,7 @@ struct iucv_irq_list {struct iucv_irq_data data; }; -static struct iucv_irq_data *iucv_irq_data; +static struct iucv_irq_data *iucv_irq_data[NR_CPUS ];static cpumask_t iucv_buffer_cpumask =CPU_MASK_NONE ;static cpumask_t iucv_irq_cpumask =CPU_MASK_NONE ;
@@ -277,7 +277,7 @@ union iucv_param {/* * Anchor for per-cpu IUCV command parameter block. */ -static union iucv_param *iucv_param; +static union iucv_param *iucv_param[NR_CPUS ];/** * iucv_call_b2f0
@@ -356,7 +356,7 @@ static void iucv_allow_cpu(void *data)* 0x10 - Flag to allow priority message completion interrupts * 0x08 - Flag to allow IUCV control interrupts */ - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[cpu];memset (parm,0 ,sizeof (union iucv_param )); parm->set_mask.ipmask =0xf8 ;iucv_call_b2f0 (IUCV_SETMASK , parm);
@@ -377,7 +377,7 @@ static void iucv_block_cpu(void *data)union iucv_param *parm;/* Disable all iucv interrupts. */ - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[cpu];memset (parm,0 ,sizeof (union iucv_param ));iucv_call_b2f0 (IUCV_SETMASK , parm);
@@ -401,9 +401,9 @@ static void iucv_declare_cpu(void *data)return ;/* Declare interrupt buffer. */ - parm =percpu_ptr (iucv_param, cpu); + parm = iucv_param[cpu];memset (parm,0 ,sizeof (union iucv_param )); - parm->db.ipbfadr1 =virt_to_phys (percpu_ptr (iucv_irq_data, cpu)); + parm->db.ipbfadr1 =virt_to_phys (iucv_irq_data[cpu]); rc =iucv_call_b2f0 (IUCV_DECLARE_BUFFER , parm);if (rc) {char *err ="Unknown" ;
@@ -458,7 +458,7 @@ static void iucv_retrieve_cpu(void *dataiucv_block_cpu (NULL );/* Retrieve interrupt buffer. */ - parm =percpu_ptr (iucv_param, cpu); + parm = iucv_param[cpu];iucv_call_b2f0 (IUCV_RETRIEVE_BUFFER , parm);/* Clear indication that an iucv buffer exists for this cpu. */
@@ -558,22 +558,23 @@ static int __cpuinit iucv_cpu_notify(strswitch (action) {case CPU_UP_PREPARE :case CPU_UP_PREPARE_FROZEN : -if (!percpu_populate (iucv_irq_data, -sizeof (struct iucv_irq_data ), -GFP_KERNEL |GFP_DMA , cpu)) + iucv_irq_data[cpu] =kmalloc_node (sizeof (struct iucv_irq_data ), +GFP_KERNEL |GFP_DMA ,cpu_to_node (cpu)); +if (!iucv_irq_data[cpu])return NOTIFY_BAD ; -if (!percpu_populate (iucv_param,sizeof (union iucv_param ), -GFP_KERNEL |GFP_DMA , cpu)) { -percpu_depopulate (iucv_irq_data, cpu); + iucv_param[cpu] =kmalloc_node (sizeof (union iucv_param ), +GFP_KERNEL |GFP_DMA ,cpu_to_node (cpu)); +if (!iucv_param[cpu])return NOTIFY_BAD ; - }break ;case CPU_UP_CANCELED :case CPU_UP_CANCELED_FROZEN :case CPU_DEAD :case CPU_DEAD_FROZEN : -percpu_depopulate (iucv_param, cpu); -percpu_depopulate (iucv_irq_data, cpu); +kfree (iucv_param[cpu]); + iucv_param[cpu] =NULL ; +kfree (iucv_irq_data[cpu]); + iucv_irq_data[cpu] =NULL ;break ;case CPU_ONLINE :case CPU_ONLINE_FROZEN :
@@ -612,7 +613,7 @@ static int iucv_sever_pathid(u16 pathid, {union iucv_param *parm; - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param ));if (userdata)memcpy (parm->ctrl.ipuser, userdata,sizeof (parm->ctrl.ipuser));
@@ -755,7 +756,7 @@ int iucv_path_accept(struct iucv_path *plocal_bh_disable ();/* Prepare parameter block. */ - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param )); parm->ctrl.ippathid = path->pathid; parm->ctrl.ipmsglim = path->msglim;
@@ -799,7 +800,7 @@ int iucv_path_connect(struct iucv_path *BUG_ON (in_atomic ());spin_lock_bh (&iucv_table_lock);iucv_cleanup_queue (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param )); parm->ctrl.ipmsglim = path->msglim; parm->ctrl.ipflags1 = path->flags;
@@ -854,7 +855,7 @@ int iucv_path_quiesce(struct iucv_path *int rc;local_bh_disable (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param ));if (userdata)memcpy (parm->ctrl.ipuser, userdata,sizeof (parm->ctrl.ipuser));
@@ -881,7 +882,7 @@ int iucv_path_resume(struct iucv_path *pint rc;local_bh_disable (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param ));if (userdata)memcpy (parm->ctrl.ipuser, userdata,sizeof (parm->ctrl.ipuser));
@@ -936,7 +937,7 @@ int iucv_message_purge(struct iucv_pathint rc;local_bh_disable (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param )); parm->purge.ippathid = path->pathid; parm->purge.ipmsgid = msg->id;
@@ -1003,7 +1004,7 @@ int iucv_message_receive(struct iucv_pat }local_bh_disable (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param )); parm->db.ipbfadr1 = (u32 )(addr_t ) buffer; parm->db.ipbfln1f = (u32 ) size;
@@ -1040,7 +1041,7 @@ int iucv_message_reject(struct iucv_pathint rc;local_bh_disable (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param )); parm->db.ippathid = path->pathid; parm->db.ipmsgid = msg->id;
@@ -1074,7 +1075,7 @@ int iucv_message_reply(struct iucv_pathint rc;local_bh_disable (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param ));if (flags &IUCV_IPRMDATA ) { parm->dpl.ippathid = path->pathid;
@@ -1118,7 +1119,7 @@ int iucv_message_send(struct iucv_path *int rc;local_bh_disable (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param ));if (flags &IUCV_IPRMDATA ) {/* Message of 8 bytes can be placed into the parameter list. */
@@ -1172,7 +1173,7 @@ int iucv_message_send2way(struct iucv_paint rc;local_bh_disable (); - parm =percpu_ptr (iucv_param,smp_processor_id ()); + parm = iucv_param[smp_processor_id ()];memset (parm,0 ,sizeof (union iucv_param ));if (flags &IUCV_IPRMDATA ) { parm->dpl.ippathid = path->pathid;
@@ -1559,7 +1560,7 @@ static void iucv_external_interrupt(u16struct iucv_irq_data *p;struct iucv_irq_list *work; - p =percpu_ptr (iucv_irq_data,smp_processor_id ()); + p = iucv_irq_data[smp_processor_id ()];if (p->ippathid >= iucv_max_pathid) { printk(KERN_WARNING "iucv_do_int: Got interrupt with " "pathid %d > max_connections (%ld)\n",
@@ -1598,6 +1599,7 @@ static void iucv_external_interrupt(u16static int __init iucv_init (void ) {int rc; +int cpu;if (!MACHINE_IS_VM ) { rc = -EPROTONOSUPPORT ;
@@ -1617,19 +1619,23 @@ static int __init iucv_init(void) rc =PTR_ERR (iucv_root); goto out_bus; } -/* Note: GFP_DMA used to get memory below 2G */ - iucv_irq_data =percpu_alloc (sizeof (struct iucv_irq_data ), -GFP_KERNEL |GFP_DMA ); -if (!iucv_irq_data) { - rc = -ENOMEM ; - goto out_root; - } -/* Allocate parameter blocks. */ - iucv_param =percpu_alloc (sizeof (union iucv_param ), -GFP_KERNEL |GFP_DMA ); -if (!iucv_param) { - rc = -ENOMEM ; - goto out_extint; + +for_each_online_cpu (cpu) { +/* Note: GFP_DMA used to get memory below 2G */ + iucv_irq_data[cpu] =kmalloc_node (sizeof (struct iucv_irq_data ), +GFP_KERNEL |GFP_DMA ,cpu_to_node (cpu)); +if (!iucv_irq_data[cpu]) { + rc = -ENOMEM ; + goto out_free; + } + +/* Allocate parameter blocks. */ + iucv_param[cpu] =kmalloc_node (sizeof (union iucv_param ), +GFP_KERNEL |GFP_DMA ,cpu_to_node (cpu)); +if (!iucv_param[cpu]) { + rc = -ENOMEM ; + goto out_free; + } }register_hotcpu_notifier (&iucv_cpu_notifier);ASCEBC (iucv_error_no_listener,16 );
@@ -1638,9 +1644,13 @@ static int __init iucv_init(void) iucv_available =1 ;return 0 ; -out_extint: -percpu_free (iucv_irq_data); -out_root: +out_free: +for_each_possible_cpu (cpu) { +kfree (iucv_param[cpu]); + iucv_param[cpu] =NULL ; +kfree (iucv_irq_data[cpu]); + iucv_irq_data[cpu] =NULL ; + }s390_root_dev_unregister (iucv_root); out_bus:bus_unregister (&iucv_bus);
@@ -1658,6 +1668,7 @@ out: static void __exit iucv_exit(void) {struct iucv_irq_list *p, *n; +int cpu;spin_lock_irq (&iucv_queue_lock);list_for_each_entry_safe (p, n, &iucv_task_queue, list)
@@ -1666,8 +1677,12 @@ static void __exit iucv_exit(void)kfree (p);spin_unlock_irq (&iucv_queue_lock);unregister_hotcpu_notifier (&iucv_cpu_notifier); -percpu_free (iucv_param); -percpu_free (iucv_irq_data); +for_each_possible_cpu (cpu) { +kfree (iucv_param[cpu]); + iucv_param[cpu] =NULL ; +kfree (iucv_irq_data[cpu]); + iucv_irq_data[cpu] =NULL ; + }s390_root_dev_unregister (iucv_root);bus_unregister (&iucv_bus);unregister_external_interrupt (0x4000 , iucv_external_interrupt);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 10/10 Fix memory detection.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Before we're getting short on memory detection fixes here is the next
one: if neither sclp nor diag260 report the storage size the detection loop will return immediately without detecting anything. Fix this by breaking the detection loop only if the memory end is known.
---
arch/s390/kernel/early.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kernel/early.c +1 -1
@@ -200,7 +200,7 @@ static noinline __init void find_memory_ cc =__tprot (addr);while (cc == old_cc) { addr +=CHUNK_INCR ; -if (addr >= memsize) +if (memsize && addr >= memsize)break ;#ifndef CONFIG_64BIT if (addr ==ADDR2G )
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.