-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 How recent of a 2.6.x kernel does this patch require? I tried applying it to a Gentoo ppc-development-sources kernel, both versions 2.6.3-benh2 and 2.6.4-pegasos0. I realize it could have failed due to Gentoo modifications to those kernels, but should it apply to these versions assuming no further modification (beyond benh patches)? (I guess I could go download the vanilla sources to find out, hehe)
I'd like to test this feature, but only 2 hunks of the entire patch seem to be suceeding (and those are a little fuzzy). Thanks. Wes Morgan On Thursday 25 March 2004 01:01 am, Benjamin Herrenschmidt wrote: > On Thu, 2004-03-25 at 17:47, Benjamin Herrenschmidt wrote: > > Hi ! > > > > I've start looking into the various issues of running > > CONFIG_PREEMPT on ppc32. I found some problems, there > > may be more, but here's a first patch that should apply on a > > recent 2.6.x. > > > > I suggest if you want to try this out that you run with the > > various kernel debugging options enabled. Report me remaining > > problems. > > And here's an updated version of that patch that doesn't break > sleep on laptops. > > Ben. > > ===== arch/ppc/kernel/entry.S 1.44 vs edited ===== > --- 1.44/arch/ppc/kernel/entry.S Mon Feb 16 18:06:27 2004 > +++ edited/arch/ppc/kernel/entry.S Thu Mar 25 14:10:41 2004 > @@ -171,9 +171,10 @@ > bl do_show_syscall > #endif /* SHOW_SYSCALLS */ > rlwinm r10,r1,0,0,18 /* current_thread_info() */ > + lwz r11,TI_LOCAL_FLAGS(r10) > + rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR > + stw r11,TI_LOCAL_FLAGS(r10) > lwz r11,TI_FLAGS(r10) > - rlwinm r11,r11,0,~_TIF_FORCE_NOERROR > - stw r11,TI_FLAGS(r10) > andi. r11,r11,_TIF_SYSCALL_TRACE > bne- syscall_dotrace > syscall_dotrace_cont: > @@ -196,8 +197,8 @@ > cmpl 0,r3,r11 > rlwinm r12,r1,0,0,18 /* current_thread_info() */ > blt+ 30f > - lwz r11,TI_FLAGS(r12) > - andi. r11,r11,_TIF_FORCE_NOERROR > + lwz r11,TI_LOCAL_FLAGS(r12) > + andi. r11,r11,_TIFL_FORCE_NOERROR > bne 30f > neg r3,r3 > lwz r10,_CCR(r1) /* Set SO bit in CR */ > ===== arch/ppc/kernel/pci.c 1.57 vs edited ===== > --- 1.57/arch/ppc/kernel/pci.c Tue Mar 23 16:42:53 2004 > +++ edited/arch/ppc/kernel/pci.c Thu Mar 25 15:09:51 2004 > @@ -1557,6 +1557,7 @@ > } > > vma->vm_pgoff = offset >> PAGE_SHIFT; > + > return ret; > } > > ===== arch/ppc/kernel/process.c 1.57 vs edited ===== > --- 1.57/arch/ppc/kernel/process.c Mon Nov 17 12:29:47 2003 > +++ edited/arch/ppc/kernel/process.c Thu Mar 25 14:35:07 2004 > @@ -164,6 +164,7 @@ > void > enable_kernel_altivec(void) > { > + preempt_disable(); > #ifdef CONFIG_SMP > if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) > giveup_altivec(current); > @@ -172,12 +173,14 @@ > #else > giveup_altivec(last_task_used_altivec); > #endif /* __SMP __ */ > + preempt_enable(); > } > #endif /* CONFIG_ALTIVEC */ > > void > enable_kernel_fp(void) > { > + preempt_disable(); > #ifdef CONFIG_SMP > if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) > giveup_fpu(current); > @@ -186,13 +189,16 @@ > #else > giveup_fpu(last_task_used_math); > #endif /* CONFIG_SMP */ > + preempt_enable(); > } > > int > dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs) > { > + preempt_disable(); > if (regs->msr & MSR_FP) > giveup_fpu(current); > + preempt_enable(); > memcpy(fpregs, ¤t->thread.fpr[0], sizeof(*fpregs)); > return 1; > } > @@ -330,12 +336,14 @@ > > if (regs == NULL) > return; > + preempt_disable(); > if (regs->msr & MSR_FP) > giveup_fpu(current); > #ifdef CONFIG_ALTIVEC > if (regs->msr & MSR_VEC) > giveup_altivec(current); > #endif /* CONFIG_ALTIVEC */ > + preempt_enable(); > } > > /* > @@ -480,12 +488,14 @@ > error = PTR_ERR(filename); > if (IS_ERR(filename)) > goto out; > + preempt_disable(); > if (regs->msr & MSR_FP) > giveup_fpu(current); > #ifdef CONFIG_ALTIVEC > if (regs->msr & MSR_VEC) > giveup_altivec(current); > #endif /* CONFIG_ALTIVEC */ > + preempt_enable(); > error = do_execve(filename, (char __user *__user *) a1, > (char __user *__user *) a2, regs); > if (error == 0) > ===== arch/ppc/kernel/traps.c 1.44 vs edited ===== > --- 1.44/arch/ppc/kernel/traps.c Tue Mar 23 12:46:58 2004 > +++ edited/arch/ppc/kernel/traps.c Thu Mar 25 13:21:47 2004 > @@ -438,8 +438,14 @@ > int code = 0; > u32 fpscr; > > + /* We must make sure the FP state is consistent with > + * our MSR_FP in regs > + */ > + preempt_disable(); > if (regs->msr & MSR_FP) > giveup_fpu(current); > + preempt_enable(); > + > fpscr = current->thread.fpscr; > fpscr &= fpscr << 22; /* mask summary bits with enables */ > if (fpscr & FPSCR_VX) > @@ -603,8 +609,11 @@ > void > AltivecAssistException(struct pt_regs *regs) > { > + preempt_disable(); > if (regs->msr & MSR_VEC) > giveup_altivec(current); > + preempt_enable(); > + > /* XXX quick hack for now: set the non-Java bit in the VSCR */ > current->thread.vscr.u[3] |= 0x10000; > } > ===== arch/ppc/syslib/prom_init.c 1.26 vs edited ===== > --- 1.26/arch/ppc/syslib/prom_init.c Sat Feb 14 19:29:14 2004 > +++ edited/arch/ppc/syslib/prom_init.c Wed Mar 24 12:35:20 2004 > @@ -44,8 +44,12 @@ > * things like "driver,AAPL,MacOS,PowerPC" properties. But this value > * does need to be big enough to ensure that we don't lose things > * like the interrupt-map property on a PCI-PCI bridge. > + * > + * 24/03/2004 - BenH: Bump that limitation to 512k and remove the > + * filter for the MacOS drivers as we may now run > + * those in a shell > */ > -#define MAX_PROPERTY_LENGTH 4096 > +#define MAX_PROPERTY_LENGTH (512 * 1024) > > #ifndef FB_MAX /* avoid pulling in all of the fb stuff > */ > #define FB_MAX 8 > ===== drivers/macintosh/adbhid.c 1.33 vs edited ===== > --- 1.33/drivers/macintosh/adbhid.c Sat Feb 14 19:29:16 2004 > +++ edited/drivers/macintosh/adbhid.c Thu Mar 25 16:16:56 2004 > @@ -107,7 +107,6 @@ > static void adbhid_probe(void); > > static void adbhid_input_keycode(int, int, int, struct pt_regs *); > -static void leds_done(struct adb_request *); > > static void init_trackpad(int id); > static void init_trackball(int id); > @@ -446,24 +445,54 @@ > > static struct adb_request led_request; > static int leds_pending[16]; > +static int leds_req_pending; > static int pending_devs[16]; > static int pending_led_start=0; > static int pending_led_end=0; > +static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED; > + > +static void leds_done(struct adb_request *req) > +{ > + int leds, device; > + unsigned long flags; > + > + spin_lock_irqsave(&leds_lock, flags); > + > + if (pending_led_start != pending_led_end) { > + device = pending_devs[pending_led_start]; > + leds = leds_pending[device] & 0xff; > + leds_pending[device] = 0; > + pending_led_start++; > + pending_led_start = (pending_led_start < 16) ? > pending_led_start : 0; > + } else > + leds_req_pending = 0; > + > + spin_unlock_irqrestore(&leds_lock, flags); > + if (leds_req_pending) > + adb_request(&led_request, leds_done, 0, 3, > + ADB_WRITEREG(device, KEYB_LEDREG), 0xff, ~leds); > +} > > static void real_leds(unsigned char leds, int device) > { > - if (led_request.complete) { > - adb_request(&led_request, leds_done, 0, 3, > - ADB_WRITEREG(device, KEYB_LEDREG), 0xff, > - ~leds); > - } else { > - if (!(leds_pending[device] & 0x100)) { > - pending_devs[pending_led_end] = device; > - pending_led_end++; > - pending_led_end = (pending_led_end < 16) ? pending_led_end : 0; > + unsigned long flags; > + > + spin_lock_irqsave(&leds_lock, flags); > + if (!leds_req_pending) { > + leds_req_pending = 1; > + spin_unlock_irqrestore(&leds_lock, flags); > + adb_request(&led_request, leds_done, 0, 3, > + ADB_WRITEREG(device, KEYB_LEDREG), 0xff, ~leds); > + return; > + } else { > + if (!(leds_pending[device] & 0x100)) { > + pending_devs[pending_led_end] = device; > + pending_led_end++; > + pending_led_end = (pending_led_end < 16) ? > pending_led_end : 0; > + } > + leds_pending[device] = leds | 0x100; > } > - leds_pending[device] = leds | 0x100; > - } > + spin_unlock_irqrestore(&leds_lock, flags); > } > > /* > @@ -487,21 +516,6 @@ > return -1; > } > > -static void leds_done(struct adb_request *req) > -{ > - int leds,device; > - > - if (pending_led_start != pending_led_end) { > - device = pending_devs[pending_led_start]; > - leds = leds_pending[device] & 0xff; > - leds_pending[device] = 0; > - pending_led_start++; > - pending_led_start = (pending_led_start < 16) ? pending_led_start : 0; > - real_leds(leds,device); > - } > - > -} > - > static int > adb_message_handler(struct notifier_block *this, unsigned long code, void > *x) { > @@ -518,7 +532,7 @@ > } > > /* Stop pending led requests */ > - while(!led_request.complete) > + while(leds_req_pending) > adb_poll(); > break; > > ===== drivers/macintosh/via-pmu.c 1.61 vs edited ===== > --- 1.61/drivers/macintosh/via-pmu.c Thu Mar 4 13:04:36 2004 > +++ edited/drivers/macintosh/via-pmu.c Thu Mar 25 18:52:00 2004 > @@ -137,7 +137,8 @@ > static int data_len; > static volatile int adb_int_pending; > static volatile int disable_poll; > -static struct adb_request bright_req_1, bright_req_2, bright_req_3; > +static struct adb_request bright_req_1, bright_req_2; > +static unsigned long async_req_locks; > static struct device_node *vias; > static int pmu_kind = PMU_UNKNOWN; > static int pmu_fully_inited = 0; > @@ -404,7 +405,6 @@ > > bright_req_1.complete = 1; > bright_req_2.complete = 1; > - bright_req_3.complete = 1; > #ifdef CONFIG_PMAC_PBOOK > batt_req.complete = 1; > if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) > @@ -710,6 +710,8 @@ > pmu_batteries[pmu_cur_battery].amperage = amperage; > pmu_batteries[pmu_cur_battery].voltage = voltage; > pmu_batteries[pmu_cur_battery].time_remaining = time; > + > + clear_bit(0, &async_req_locks); > } > > static void __pmac > @@ -785,12 +787,14 @@ > pmu_batteries[pmu_cur_battery].time_remaining = 0; > > pmu_cur_battery = (pmu_cur_battery + 1) % pmu_battery_count; > + > + clear_bit(0, &async_req_locks); > } > > static void __pmac > query_battery_state(void) > { > - if (!batt_req.complete) > + if (test_and_set_bit(0, &async_req_locks)) > return; > if (pmu_kind == PMU_OHARE_BASED) > pmu_request(&batt_req, done_battery_state_ohare, > @@ -1690,20 +1694,30 @@ > return 0; > } > > +static void __openfirmware > +pmu_bright_complete(struct adb_request *req) > +{ > + if (req == &bright_req_1) > + clear_bit(1, &async_req_locks); > + if (req == &bright_req_2) > + clear_bit(2, &async_req_locks); > +} > + > static int __openfirmware > pmu_set_backlight_level(int level, void* data) > { > if (vias == NULL) > return -ENODEV; > > - if (!bright_req_1.complete) > + if (test_and_set_bit(1, &async_req_locks)) > return -EAGAIN; > - pmu_request(&bright_req_1, NULL, 2, PMU_BACKLIGHT_BRIGHT, > + pmu_request(&bright_req_1, pmu_bright_complete, 2, PMU_BACKLIGHT_BRIGHT, > backlight_to_bright[level]); > - if (!bright_req_2.complete) > + if (test_and_set_bit(2, &async_req_locks)) > return -EAGAIN; > - pmu_request(&bright_req_2, NULL, 2, PMU_POWER_CTRL, PMU_POW_BACKLIGHT > - | (level > BACKLIGHT_OFF ? PMU_POW_ON : PMU_POW_OFF)); > + pmu_request(&bright_req_2, pmu_bright_complete, 2, PMU_POWER_CTRL, > + PMU_POW_BACKLIGHT | (level > BACKLIGHT_OFF ? > + PMU_POW_ON : PMU_POW_OFF)); > > return 0; > } > @@ -2330,6 +2344,8 @@ > return -EBUSY; > } > > + preempt_disable(); > + > /* Make sure the decrementer won't interrupt us */ > asm volatile("mtdec %0" : : "r" (0x7fffffff)); > /* Make sure any pending DEC interrupt occurring while we did > @@ -2352,6 +2368,7 @@ > if (ret) { > wakeup_decrementer(); > local_irq_enable(); > + preempt_enable(); > device_resume(); > broadcast_wake(); > printk(KERN_ERR "Driver powerdown failed\n"); > @@ -2360,7 +2377,8 @@ > > /* Wait for completion of async backlight requests */ > while (!bright_req_1.complete || !bright_req_2.complete || > - !bright_req_3.complete || !batt_req.complete) > + > + !batt_req.complete) > pmu_poll(); > > /* Giveup the lazy FPU & vec so we don't have to back them > @@ -2398,6 +2416,8 @@ > > pmu_blink(1); > > + preempt_enable(); > + > /* Resume devices */ > device_resume(); > > @@ -2673,9 +2693,9 @@ > mb(); > > pmac_wakeup_devices(); > - > pbook_free_pci_save(); > iounmap(mem_ctrl); > + > return 0; > } > > ===== include/asm-ppc/ptrace.h 1.11 vs edited ===== > --- 1.11/include/asm-ppc/ptrace.h Tue Jun 24 14:45:56 2003 > +++ edited/include/asm-ppc/ptrace.h Thu Mar 25 14:02:44 2004 > @@ -49,7 +49,10 @@ > #define instruction_pointer(regs) ((regs)->nip) > #define user_mode(regs) (((regs)->msr & MSR_PR) != 0) > > -#define force_successful_syscall_return() > set_thread_flag(TIF_FORCE_NOERROR) +#define > force_successful_syscall_return() \ > + do { \ > + current_thread_info()->local_flags |= _TIFL_FORCE_NOERROR; \ > + } while(0) > > /* > * We use the least-significant bit of the trap field to indicate > ===== include/asm-ppc/thread_info.h 1.17 vs edited ===== > --- 1.17/include/asm-ppc/thread_info.h Tue Oct 14 17:28:08 2003 > +++ edited/include/asm-ppc/thread_info.h Thu Mar 25 14:03:56 2004 > @@ -18,6 +18,7 @@ > struct task_struct *task; /* main task structure */ > struct exec_domain *exec_domain; /* execution domain */ > unsigned long flags; /* low level flags */ > + unsigned long local_flags; /* non-racy flags */ > int cpu; /* cpu we're on */ > int preempt_count; > struct restart_block restart_block; > @@ -28,6 +29,7 @@ > .task = &tsk, \ > .exec_domain = &default_exec_domain, \ > .flags = 0, \ > + .local_flags = 0, \ > .cpu = 0, \ > .preempt_count = 1, \ > .restart_block = { \ > @@ -69,8 +71,9 @@ > #define TI_TASK 0 > #define TI_EXECDOMAIN 4 > #define TI_FLAGS 8 > -#define TI_CPU 12 > -#define TI_PREEMPT 16 > +#define TI_LOCAL_FLAGS 12 > +#define TI_CPU 16 > +#define TI_PREEMPT 20 > > #define PREEMPT_ACTIVE 0x4000000 > > @@ -83,16 +86,22 @@ > #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ > #define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling > TIF_NEED_RESCHED */ > -#define TIF_FORCE_NOERROR 5 /* don't return error from current > - syscall even if result < 0 */ > - > /* as above, but as bit values */ > #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) > #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) > #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) > #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) > #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) > -#define _TIF_FORCE_NOERROR (1<<TIF_FORCE_NOERROR) > + > +/* > + * Non racy (local) flags bit numbers > + */ > +#define TIFL_FORCE_NOERROR 0 /* don't return error from current > + syscall even if result < 0 */ > + > +/* as above, but as bit values */ > +#define _TIFL_FORCE_NOERROR (1<<TIFL_FORCE_NOERROR) > + > > #endif /* __KERNEL__ */ > > ===== sound/oss/dmasound/dmasound_core.c 1.22 vs edited ===== > --- 1.22/sound/oss/dmasound/dmasound_core.c Mon Feb 9 13:18:52 2004 > +++ edited/sound/oss/dmasound/dmasound_core.c Thu Mar 25 18:41:02 2004 > @@ -1004,6 +1004,7 @@ > static int sq_fsync(struct file *filp, struct dentry *dentry) > { > int rc = 0; > + int timeout = 5; > > write_sq.syncing |= 1; > sq_play(); /* there may be an incomplete frame waiting */ > @@ -1016,6 +1017,12 @@ > * and clear the queue. */ > sq_reset_output(); > rc = -EINTR; > + break; > + } > + if (!--timeout) { > + printk(KERN_WARNING "dmasound: Timeout draining > output\n"); > + sq_reset_output(); > + rc = -EIO; > break; > } > } - -- We shall not cease from exploration And the end of all our exploring Will be to arrive where we started And know the place for the first time. - - T. S. Eliot - ---------------------------------- Libretech.org - Technology Is Free (http://www.libretech.org) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFAbg99I89ooLagmnQRAvPfAKCXEtXtmWmZJjxBzecz0wXY4GWuQwCgwNuQ NxvG+7/YKYK3WoAZHZz5si0= =7XME -----END PGP SIGNATURE-----