diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-25 19:53:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-25 19:53:16 -0400 |
commit | ce7d0226198aac42ed311dd2783232adc16b296d (patch) | |
tree | 64ae863b9fbae4cd16da8a2d8553573bd676e23c /arch | |
parent | b142ebb61cd36370c6fac5e0b8261a6cd7bba782 (diff) | |
parent | a75f5f0f0a3676216e0015b3040c785dbfe1e0da (diff) |
Merge branch 'alpha-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha-2.6
* 'alpha-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha-2.6:
alpha: simplify and optimize sched_find_first_bit
alpha: invoke oom-killer from page fault
Convert alpha to use clocksources instead of arch_gettimeoffset
Diffstat (limited to 'arch')
-rw-r--r-- | arch/alpha/Kconfig | 4 | ||||
-rw-r--r-- | arch/alpha/include/asm/bitops.h | 20 | ||||
-rw-r--r-- | arch/alpha/kernel/time.c | 69 | ||||
-rw-r--r-- | arch/alpha/mm/fault.c | 11 |
4 files changed, 42 insertions, 62 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index b7193986cbf9..24efdfe277fc 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -51,10 +51,6 @@ config GENERIC_TIME | |||
51 | bool | 51 | bool |
52 | default y | 52 | default y |
53 | 53 | ||
54 | config ARCH_USES_GETTIMEOFFSET | ||
55 | bool | ||
56 | default y | ||
57 | |||
58 | config GENERIC_CMOS_UPDATE | 54 | config GENERIC_CMOS_UPDATE |
59 | def_bool y | 55 | def_bool y |
60 | 56 | ||
diff --git a/arch/alpha/include/asm/bitops.h b/arch/alpha/include/asm/bitops.h index 296da1d5ed57..1dce24bc455a 100644 --- a/arch/alpha/include/asm/bitops.h +++ b/arch/alpha/include/asm/bitops.h | |||
@@ -438,22 +438,20 @@ static inline unsigned int __arch_hweight8(unsigned int w) | |||
438 | 438 | ||
439 | /* | 439 | /* |
440 | * Every architecture must define this function. It's the fastest | 440 | * Every architecture must define this function. It's the fastest |
441 | * way of searching a 140-bit bitmap where the first 100 bits are | 441 | * way of searching a 100-bit bitmap. It's guaranteed that at least |
442 | * unlikely to be set. It's guaranteed that at least one of the 140 | 442 | * one of the 100 bits is cleared. |
443 | * bits is set. | ||
444 | */ | 443 | */ |
445 | static inline unsigned long | 444 | static inline unsigned long |
446 | sched_find_first_bit(unsigned long b[3]) | 445 | sched_find_first_bit(const unsigned long b[2]) |
447 | { | 446 | { |
448 | unsigned long b0 = b[0], b1 = b[1], b2 = b[2]; | 447 | unsigned long b0, b1, ofs, tmp; |
449 | unsigned long ofs; | ||
450 | 448 | ||
451 | ofs = (b1 ? 64 : 128); | 449 | b0 = b[0]; |
452 | b1 = (b1 ? b1 : b2); | 450 | b1 = b[1]; |
453 | ofs = (b0 ? 0 : ofs); | 451 | ofs = (b0 ? 0 : 64); |
454 | b0 = (b0 ? b0 : b1); | 452 | tmp = (b0 ? b0 : b1); |
455 | 453 | ||
456 | return __ffs(b0) + ofs; | 454 | return __ffs(tmp) + ofs; |
457 | } | 455 | } |
458 | 456 | ||
459 | #include <asm-generic/bitops/ext2-non-atomic.h> | 457 | #include <asm-generic/bitops/ext2-non-atomic.h> |
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 5465e932e568..1efbed82c0fd 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/mc146818rtc.h> | 51 | #include <linux/mc146818rtc.h> |
52 | #include <linux/time.h> | 52 | #include <linux/time.h> |
53 | #include <linux/timex.h> | 53 | #include <linux/timex.h> |
54 | #include <linux/clocksource.h> | ||
54 | 55 | ||
55 | #include "proto.h" | 56 | #include "proto.h" |
56 | #include "irq_impl.h" | 57 | #include "irq_impl.h" |
@@ -332,6 +333,34 @@ rpcc_after_update_in_progress(void) | |||
332 | return rpcc(); | 333 | return rpcc(); |
333 | } | 334 | } |
334 | 335 | ||
336 | #ifndef CONFIG_SMP | ||
337 | /* Until and unless we figure out how to get cpu cycle counters | ||
338 | in sync and keep them there, we can't use the rpcc. */ | ||
339 | static cycle_t read_rpcc(struct clocksource *cs) | ||
340 | { | ||
341 | cycle_t ret = (cycle_t)rpcc(); | ||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | static struct clocksource clocksource_rpcc = { | ||
346 | .name = "rpcc", | ||
347 | .rating = 300, | ||
348 | .read = read_rpcc, | ||
349 | .mask = CLOCKSOURCE_MASK(32), | ||
350 | .flags = CLOCK_SOURCE_IS_CONTINUOUS | ||
351 | }; | ||
352 | |||
353 | static inline void register_rpcc_clocksource(long cycle_freq) | ||
354 | { | ||
355 | clocksource_calc_mult_shift(&clocksource_rpcc, cycle_freq, 4); | ||
356 | clocksource_register(&clocksource_rpcc); | ||
357 | } | ||
358 | #else /* !CONFIG_SMP */ | ||
359 | static inline void register_rpcc_clocksource(long cycle_freq) | ||
360 | { | ||
361 | } | ||
362 | #endif /* !CONFIG_SMP */ | ||
363 | |||
335 | void __init | 364 | void __init |
336 | time_init(void) | 365 | time_init(void) |
337 | { | 366 | { |
@@ -385,6 +414,8 @@ time_init(void) | |||
385 | __you_loose(); | 414 | __you_loose(); |
386 | } | 415 | } |
387 | 416 | ||
417 | register_rpcc_clocksource(cycle_freq); | ||
418 | |||
388 | state.last_time = cc1; | 419 | state.last_time = cc1; |
389 | state.scaled_ticks_per_cycle | 420 | state.scaled_ticks_per_cycle |
390 | = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; | 421 | = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; |
@@ -395,44 +426,6 @@ time_init(void) | |||
395 | } | 426 | } |
396 | 427 | ||
397 | /* | 428 | /* |
398 | * Use the cycle counter to estimate an displacement from the last time | ||
399 | * tick. Unfortunately the Alpha designers made only the low 32-bits of | ||
400 | * the cycle counter active, so we overflow on 8.2 seconds on a 500MHz | ||
401 | * part. So we can't do the "find absolute time in terms of cycles" thing | ||
402 | * that the other ports do. | ||
403 | */ | ||
404 | u32 arch_gettimeoffset(void) | ||
405 | { | ||
406 | #ifdef CONFIG_SMP | ||
407 | /* Until and unless we figure out how to get cpu cycle counters | ||
408 | in sync and keep them there, we can't use the rpcc tricks. */ | ||
409 | return 0; | ||
410 | #else | ||
411 | unsigned long delta_cycles, delta_usec, partial_tick; | ||
412 | |||
413 | delta_cycles = rpcc() - state.last_time; | ||
414 | partial_tick = state.partial_tick; | ||
415 | /* | ||
416 | * usec = cycles * ticks_per_cycle * 2**48 * 1e6 / (2**48 * ticks) | ||
417 | * = cycles * (s_t_p_c) * 1e6 / (2**48 * ticks) | ||
418 | * = cycles * (s_t_p_c) * 15625 / (2**42 * ticks) | ||
419 | * | ||
420 | * which, given a 600MHz cycle and a 1024Hz tick, has a | ||
421 | * dynamic range of about 1.7e17, which is less than the | ||
422 | * 1.8e19 in an unsigned long, so we are safe from overflow. | ||
423 | * | ||
424 | * Round, but with .5 up always, since .5 to even is harder | ||
425 | * with no clear gain. | ||
426 | */ | ||
427 | |||
428 | delta_usec = (delta_cycles * state.scaled_ticks_per_cycle | ||
429 | + partial_tick) * 15625; | ||
430 | delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; | ||
431 | return delta_usec * 1000; | ||
432 | #endif | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | * In order to set the CMOS clock precisely, set_rtc_mmss has to be | 429 | * In order to set the CMOS clock precisely, set_rtc_mmss has to be |
437 | * called 500 ms after the second nowtime has started, because when | 430 | * called 500 ms after the second nowtime has started, because when |
438 | * nowtime is written into the registers of the CMOS clock, it will | 431 | * nowtime is written into the registers of the CMOS clock, it will |
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index 00a31deaa96e..fadd5f882ff9 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c | |||
@@ -142,7 +142,6 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
142 | goto bad_area; | 142 | goto bad_area; |
143 | } | 143 | } |
144 | 144 | ||
145 | survive: | ||
146 | /* If for any reason at all we couldn't handle the fault, | 145 | /* If for any reason at all we couldn't handle the fault, |
147 | make sure we exit gracefully rather than endlessly redo | 146 | make sure we exit gracefully rather than endlessly redo |
148 | the fault. */ | 147 | the fault. */ |
@@ -188,16 +187,10 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
188 | /* We ran out of memory, or some other thing happened to us that | 187 | /* We ran out of memory, or some other thing happened to us that |
189 | made us unable to handle the page fault gracefully. */ | 188 | made us unable to handle the page fault gracefully. */ |
190 | out_of_memory: | 189 | out_of_memory: |
191 | if (is_global_init(current)) { | ||
192 | yield(); | ||
193 | down_read(&mm->mmap_sem); | ||
194 | goto survive; | ||
195 | } | ||
196 | printk(KERN_ALERT "VM: killing process %s(%d)\n", | ||
197 | current->comm, task_pid_nr(current)); | ||
198 | if (!user_mode(regs)) | 190 | if (!user_mode(regs)) |
199 | goto no_context; | 191 | goto no_context; |
200 | do_group_exit(SIGKILL); | 192 | pagefault_out_of_memory(); |
193 | return; | ||
201 | 194 | ||
202 | do_sigbus: | 195 | do_sigbus: |
203 | /* Send a sigbus, regardless of whether we were in kernel | 196 | /* Send a sigbus, regardless of whether we were in kernel |