diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-02-20 19:13:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-02-20 19:13:39 -0500 |
commit | 39e255dab5a993cbebb35598015da1d4a0eb3727 (patch) | |
tree | 3994bee56175ff08d09a6b2de5783456252833d6 | |
parent | 1a4edd9072d3826f1b1234a9b3cc69fcfdebdbfa (diff) | |
parent | cf1eb40f8f5ea12c9e569e7282161fc7f194fd62 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
[S390] correct ktime to tod clock comparator conversion
[S390] 3215 deadlock with tty_wakeup
[S390] incorrect PageTables counter for kvm page tables
[S390] idle: avoid RCU usage in extended quiescent state
-rw-r--r-- | arch/s390/kernel/process.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 7 | ||||
-rw-r--r-- | arch/s390/mm/pgtable.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/con3215.c | 22 |
4 files changed, 24 insertions, 12 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 3201ae447990..4261aa799774 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -76,7 +76,6 @@ static void default_idle(void) | |||
76 | if (test_thread_flag(TIF_MCCK_PENDING)) { | 76 | if (test_thread_flag(TIF_MCCK_PENDING)) { |
77 | local_mcck_enable(); | 77 | local_mcck_enable(); |
78 | local_irq_enable(); | 78 | local_irq_enable(); |
79 | s390_handle_mcck(); | ||
80 | return; | 79 | return; |
81 | } | 80 | } |
82 | trace_hardirqs_on(); | 81 | trace_hardirqs_on(); |
@@ -93,10 +92,12 @@ void cpu_idle(void) | |||
93 | for (;;) { | 92 | for (;;) { |
94 | tick_nohz_idle_enter(); | 93 | tick_nohz_idle_enter(); |
95 | rcu_idle_enter(); | 94 | rcu_idle_enter(); |
96 | while (!need_resched()) | 95 | while (!need_resched() && !test_thread_flag(TIF_MCCK_PENDING)) |
97 | default_idle(); | 96 | default_idle(); |
98 | rcu_idle_exit(); | 97 | rcu_idle_exit(); |
99 | tick_nohz_idle_exit(); | 98 | tick_nohz_idle_exit(); |
99 | if (test_thread_flag(TIF_MCCK_PENDING)) | ||
100 | s390_handle_mcck(); | ||
100 | preempt_enable_no_resched(); | 101 | preempt_enable_no_resched(); |
101 | schedule(); | 102 | schedule(); |
102 | preempt_disable(); | 103 | preempt_disable(); |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index fa02f443f5f6..14da278febbf 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -113,11 +113,14 @@ static void fixup_clock_comparator(unsigned long long delta) | |||
113 | static int s390_next_ktime(ktime_t expires, | 113 | static int s390_next_ktime(ktime_t expires, |
114 | struct clock_event_device *evt) | 114 | struct clock_event_device *evt) |
115 | { | 115 | { |
116 | struct timespec ts; | ||
116 | u64 nsecs; | 117 | u64 nsecs; |
117 | 118 | ||
118 | nsecs = ktime_to_ns(ktime_sub(expires, ktime_get_monotonic_offset())); | 119 | ts.tv_sec = ts.tv_nsec = 0; |
120 | monotonic_to_bootbased(&ts); | ||
121 | nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires)); | ||
119 | do_div(nsecs, 125); | 122 | do_div(nsecs, 125); |
120 | S390_lowcore.clock_comparator = TOD_UNIX_EPOCH + (nsecs << 9); | 123 | S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9); |
121 | set_clock_comparator(S390_lowcore.clock_comparator); | 124 | set_clock_comparator(S390_lowcore.clock_comparator); |
122 | return 0; | 125 | return 0; |
123 | } | 126 | } |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 9a4d02f64f16..51b0738e13d1 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -574,7 +574,7 @@ static inline void page_table_free_pgste(unsigned long *table) | |||
574 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | 574 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); |
575 | mp = (struct gmap_pgtable *) page->index; | 575 | mp = (struct gmap_pgtable *) page->index; |
576 | BUG_ON(!list_empty(&mp->mapper)); | 576 | BUG_ON(!list_empty(&mp->mapper)); |
577 | pgtable_page_ctor(page); | 577 | pgtable_page_dtor(page); |
578 | atomic_set(&page->_mapcount, -1); | 578 | atomic_set(&page->_mapcount, -1); |
579 | kfree(mp); | 579 | kfree(mp); |
580 | __free_page(page); | 580 | __free_page(page); |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 934458ad55e5..e71a50d4b221 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -87,6 +87,7 @@ struct raw3215_info { | |||
87 | struct tty_struct *tty; /* pointer to tty structure if present */ | 87 | struct tty_struct *tty; /* pointer to tty structure if present */ |
88 | struct raw3215_req *queued_read; /* pointer to queued read requests */ | 88 | struct raw3215_req *queued_read; /* pointer to queued read requests */ |
89 | struct raw3215_req *queued_write;/* pointer to queued write requests */ | 89 | struct raw3215_req *queued_write;/* pointer to queued write requests */ |
90 | struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */ | ||
90 | wait_queue_head_t empty_wait; /* wait queue for flushing */ | 91 | wait_queue_head_t empty_wait; /* wait queue for flushing */ |
91 | struct timer_list timer; /* timer for delayed output */ | 92 | struct timer_list timer; /* timer for delayed output */ |
92 | int line_pos; /* position on the line (for tabs) */ | 93 | int line_pos; /* position on the line (for tabs) */ |
@@ -334,19 +335,23 @@ static inline void raw3215_try_io(struct raw3215_info *raw) | |||
334 | } | 335 | } |
335 | 336 | ||
336 | /* | 337 | /* |
338 | * Call tty_wakeup from tasklet context | ||
339 | */ | ||
340 | static void raw3215_wakeup(unsigned long data) | ||
341 | { | ||
342 | struct raw3215_info *raw = (struct raw3215_info *) data; | ||
343 | tty_wakeup(raw->tty); | ||
344 | } | ||
345 | |||
346 | /* | ||
337 | * Try to start the next IO and wake up processes waiting on the tty. | 347 | * Try to start the next IO and wake up processes waiting on the tty. |
338 | */ | 348 | */ |
339 | static void raw3215_next_io(struct raw3215_info *raw) | 349 | static void raw3215_next_io(struct raw3215_info *raw) |
340 | { | 350 | { |
341 | struct tty_struct *tty; | ||
342 | |||
343 | raw3215_mk_write_req(raw); | 351 | raw3215_mk_write_req(raw); |
344 | raw3215_try_io(raw); | 352 | raw3215_try_io(raw); |
345 | tty = raw->tty; | 353 | if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) |
346 | if (tty != NULL && | 354 | tasklet_schedule(&raw->tlet); |
347 | RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) { | ||
348 | tty_wakeup(tty); | ||
349 | } | ||
350 | } | 355 | } |
351 | 356 | ||
352 | /* | 357 | /* |
@@ -682,6 +687,7 @@ static int raw3215_probe (struct ccw_device *cdev) | |||
682 | return -ENOMEM; | 687 | return -ENOMEM; |
683 | } | 688 | } |
684 | init_waitqueue_head(&raw->empty_wait); | 689 | init_waitqueue_head(&raw->empty_wait); |
690 | tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw); | ||
685 | 691 | ||
686 | dev_set_drvdata(&cdev->dev, raw); | 692 | dev_set_drvdata(&cdev->dev, raw); |
687 | cdev->handler = raw3215_irq; | 693 | cdev->handler = raw3215_irq; |
@@ -901,6 +907,7 @@ static int __init con3215_init(void) | |||
901 | 907 | ||
902 | raw->flags |= RAW3215_FIXED; | 908 | raw->flags |= RAW3215_FIXED; |
903 | init_waitqueue_head(&raw->empty_wait); | 909 | init_waitqueue_head(&raw->empty_wait); |
910 | tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw); | ||
904 | 911 | ||
905 | /* Request the console irq */ | 912 | /* Request the console irq */ |
906 | if (raw3215_startup(raw) != 0) { | 913 | if (raw3215_startup(raw) != 0) { |
@@ -966,6 +973,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp) | |||
966 | tty->closing = 1; | 973 | tty->closing = 1; |
967 | /* Shutdown the terminal */ | 974 | /* Shutdown the terminal */ |
968 | raw3215_shutdown(raw); | 975 | raw3215_shutdown(raw); |
976 | tasklet_kill(&raw->tlet); | ||
969 | tty->closing = 0; | 977 | tty->closing = 0; |
970 | raw->tty = NULL; | 978 | raw->tty = NULL; |
971 | } | 979 | } |