diff options
| -rw-r--r-- | drivers/pci/setup-bus.c | 5 | ||||
| -rw-r--r-- | include/linux/sched.h | 6 | ||||
| -rw-r--r-- | kernel/relay.c | 7 | ||||
| -rw-r--r-- | kernel/sched.c | 43 | ||||
| -rw-r--r-- | kernel/time/clocksource.c | 2 | ||||
| -rw-r--r-- | kernel/timer.c | 10 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 21 |
7 files changed, 76 insertions, 18 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 125e7b7f34ff..f7cb8e0758b4 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -486,12 +486,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) | |||
| 486 | break; | 486 | break; |
| 487 | 487 | ||
| 488 | case PCI_CLASS_BRIDGE_PCI: | 488 | case PCI_CLASS_BRIDGE_PCI: |
| 489 | /* don't size subtractive decoding (transparent) | ||
| 490 | * PCI-to-PCI bridges */ | ||
| 491 | if (bus->self->transparent) | ||
| 492 | break; | ||
| 493 | pci_bridge_check_ranges(bus); | 489 | pci_bridge_check_ranges(bus); |
| 494 | /* fall through */ | ||
| 495 | default: | 490 | default: |
| 496 | pbus_size_io(bus); | 491 | pbus_size_io(bus); |
| 497 | /* If the bridge supports prefetchable range, size it | 492 | /* If the bridge supports prefetchable range, size it |
diff --git a/include/linux/sched.h b/include/linux/sched.h index fed07d03364e..6a1e7afb099b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -1541,6 +1541,12 @@ static inline void idle_task_exit(void) {} | |||
| 1541 | 1541 | ||
| 1542 | extern void sched_idle_next(void); | 1542 | extern void sched_idle_next(void); |
| 1543 | 1543 | ||
| 1544 | #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) | ||
| 1545 | extern void wake_up_idle_cpu(int cpu); | ||
| 1546 | #else | ||
| 1547 | static inline void wake_up_idle_cpu(int cpu) { } | ||
| 1548 | #endif | ||
| 1549 | |||
| 1544 | #ifdef CONFIG_SCHED_DEBUG | 1550 | #ifdef CONFIG_SCHED_DEBUG |
| 1545 | extern unsigned int sysctl_sched_latency; | 1551 | extern unsigned int sysctl_sched_latency; |
| 1546 | extern unsigned int sysctl_sched_min_granularity; | 1552 | extern unsigned int sysctl_sched_min_granularity; |
diff --git a/kernel/relay.c b/kernel/relay.c index 4c035a8a248c..d6204a485818 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
| @@ -736,7 +736,7 @@ static int relay_file_open(struct inode *inode, struct file *filp) | |||
| 736 | kref_get(&buf->kref); | 736 | kref_get(&buf->kref); |
| 737 | filp->private_data = buf; | 737 | filp->private_data = buf; |
| 738 | 738 | ||
| 739 | return 0; | 739 | return nonseekable_open(inode, filp); |
| 740 | } | 740 | } |
| 741 | 741 | ||
| 742 | /** | 742 | /** |
| @@ -1056,6 +1056,10 @@ static struct pipe_buf_operations relay_pipe_buf_ops = { | |||
| 1056 | .get = generic_pipe_buf_get, | 1056 | .get = generic_pipe_buf_get, |
| 1057 | }; | 1057 | }; |
| 1058 | 1058 | ||
| 1059 | static void relay_page_release(struct splice_pipe_desc *spd, unsigned int i) | ||
| 1060 | { | ||
| 1061 | } | ||
| 1062 | |||
| 1059 | /* | 1063 | /* |
| 1060 | * subbuf_splice_actor - splice up to one subbuf's worth of data | 1064 | * subbuf_splice_actor - splice up to one subbuf's worth of data |
| 1061 | */ | 1065 | */ |
| @@ -1083,6 +1087,7 @@ static int subbuf_splice_actor(struct file *in, | |||
| 1083 | .partial = partial, | 1087 | .partial = partial, |
| 1084 | .flags = flags, | 1088 | .flags = flags, |
| 1085 | .ops = &relay_pipe_buf_ops, | 1089 | .ops = &relay_pipe_buf_ops, |
| 1090 | .spd_release = relay_page_release, | ||
| 1086 | }; | 1091 | }; |
| 1087 | 1092 | ||
| 1088 | if (rbuf->subbufs_produced == rbuf->subbufs_consumed) | 1093 | if (rbuf->subbufs_produced == rbuf->subbufs_consumed) |
diff --git a/kernel/sched.c b/kernel/sched.c index 28c73f07efb2..8dcdec6fe0fe 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -1052,6 +1052,49 @@ static void resched_cpu(int cpu) | |||
| 1052 | resched_task(cpu_curr(cpu)); | 1052 | resched_task(cpu_curr(cpu)); |
| 1053 | spin_unlock_irqrestore(&rq->lock, flags); | 1053 | spin_unlock_irqrestore(&rq->lock, flags); |
| 1054 | } | 1054 | } |
| 1055 | |||
| 1056 | #ifdef CONFIG_NO_HZ | ||
| 1057 | /* | ||
| 1058 | * When add_timer_on() enqueues a timer into the timer wheel of an | ||
| 1059 | * idle CPU then this timer might expire before the next timer event | ||
| 1060 | * which is scheduled to wake up that CPU. In case of a completely | ||
| 1061 | * idle system the next event might even be infinite time into the | ||
| 1062 | * future. wake_up_idle_cpu() ensures that the CPU is woken up and | ||
| 1063 | * leaves the inner idle loop so the newly added timer is taken into | ||
| 1064 | * account when the CPU goes back to idle and evaluates the timer | ||
| 1065 | * wheel for the next timer event. | ||
| 1066 | */ | ||
| 1067 | void wake_up_idle_cpu(int cpu) | ||
| 1068 | { | ||
| 1069 | struct rq *rq = cpu_rq(cpu); | ||
| 1070 | |||
| 1071 | if (cpu == smp_processor_id()) | ||
| 1072 | return; | ||
| 1073 | |||
| 1074 | /* | ||
| 1075 | * This is safe, as this function is called with the timer | ||
| 1076 | * wheel base lock of (cpu) held. When the CPU is on the way | ||
| 1077 | * to idle and has not yet set rq->curr to idle then it will | ||
| 1078 | * be serialized on the timer wheel base lock and take the new | ||
| 1079 | * timer into account automatically. | ||
| 1080 | */ | ||
| 1081 | if (rq->curr != rq->idle) | ||
| 1082 | return; | ||
| 1083 | |||
| 1084 | /* | ||
| 1085 | * We can set TIF_RESCHED on the idle task of the other CPU | ||
| 1086 | * lockless. The worst case is that the other CPU runs the | ||
| 1087 | * idle task through an additional NOOP schedule() | ||
| 1088 | */ | ||
| 1089 | set_tsk_thread_flag(rq->idle, TIF_NEED_RESCHED); | ||
| 1090 | |||
| 1091 | /* NEED_RESCHED must be visible before we test polling */ | ||
| 1092 | smp_mb(); | ||
| 1093 | if (!tsk_is_polling(rq->idle)) | ||
| 1094 | smp_send_reschedule(cpu); | ||
| 1095 | } | ||
| 1096 | #endif | ||
| 1097 | |||
| 1055 | #else | 1098 | #else |
| 1056 | static void __resched_task(struct task_struct *p, int tif_bit) | 1099 | static void __resched_task(struct task_struct *p, int tif_bit) |
| 1057 | { | 1100 | { |
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 278534bbca95..7f60097d443a 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
| @@ -174,7 +174,7 @@ static void clocksource_check_watchdog(struct clocksource *cs) | |||
| 174 | if (watchdog) | 174 | if (watchdog) |
| 175 | del_timer(&watchdog_timer); | 175 | del_timer(&watchdog_timer); |
| 176 | watchdog = cs; | 176 | watchdog = cs; |
| 177 | init_timer_deferrable(&watchdog_timer); | 177 | init_timer(&watchdog_timer); |
| 178 | watchdog_timer.function = clocksource_watchdog; | 178 | watchdog_timer.function = clocksource_watchdog; |
| 179 | 179 | ||
| 180 | /* Reset watchdog cycles */ | 180 | /* Reset watchdog cycles */ |
diff --git a/kernel/timer.c b/kernel/timer.c index 99b00a25f88b..b024106daa70 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -451,10 +451,18 @@ void add_timer_on(struct timer_list *timer, int cpu) | |||
| 451 | spin_lock_irqsave(&base->lock, flags); | 451 | spin_lock_irqsave(&base->lock, flags); |
| 452 | timer_set_base(timer, base); | 452 | timer_set_base(timer, base); |
| 453 | internal_add_timer(base, timer); | 453 | internal_add_timer(base, timer); |
| 454 | /* | ||
| 455 | * Check whether the other CPU is idle and needs to be | ||
| 456 | * triggered to reevaluate the timer wheel when nohz is | ||
| 457 | * active. We are protected against the other CPU fiddling | ||
| 458 | * with the timer by holding the timer base lock. This also | ||
| 459 | * makes sure that a CPU on the way to idle can not evaluate | ||
| 460 | * the timer wheel. | ||
| 461 | */ | ||
| 462 | wake_up_idle_cpu(cpu); | ||
| 454 | spin_unlock_irqrestore(&base->lock, flags); | 463 | spin_unlock_irqrestore(&base->lock, flags); |
| 455 | } | 464 | } |
| 456 | 465 | ||
| 457 | |||
| 458 | /** | 466 | /** |
| 459 | * mod_timer - modify a timer's timeout | 467 | * mod_timer - modify a timer's timeout |
| 460 | * @timer: the timer to be modified | 468 | * @timer: the timer to be modified |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 971271602dd0..c22d6b6f2db4 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | |||
| @@ -322,15 +322,6 @@ next_sge: | |||
| 322 | ctxt->direction = DMA_FROM_DEVICE; | 322 | ctxt->direction = DMA_FROM_DEVICE; |
| 323 | clear_bit(RDMACTXT_F_READ_DONE, &ctxt->flags); | 323 | clear_bit(RDMACTXT_F_READ_DONE, &ctxt->flags); |
| 324 | clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); | 324 | clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); |
| 325 | if ((ch+1)->rc_discrim == 0) { | ||
| 326 | /* | ||
| 327 | * Checked in sq_cq_reap to see if we need to | ||
| 328 | * be enqueued | ||
| 329 | */ | ||
| 330 | set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); | ||
| 331 | ctxt->next = hdr_ctxt; | ||
| 332 | hdr_ctxt->next = head; | ||
| 333 | } | ||
| 334 | 325 | ||
| 335 | /* Prepare READ WR */ | 326 | /* Prepare READ WR */ |
| 336 | memset(&read_wr, 0, sizeof read_wr); | 327 | memset(&read_wr, 0, sizeof read_wr); |
| @@ -348,7 +339,17 @@ next_sge: | |||
| 348 | rdma_set_ctxt_sge(ctxt, &sge[ch_sge_ary[ch_no].start], | 339 | rdma_set_ctxt_sge(ctxt, &sge[ch_sge_ary[ch_no].start], |
| 349 | &sgl_offset, | 340 | &sgl_offset, |
| 350 | read_wr.num_sge); | 341 | read_wr.num_sge); |
| 351 | 342 | if (((ch+1)->rc_discrim == 0) && | |
| 343 | (read_wr.num_sge == ch_sge_ary[ch_no].count)) { | ||
| 344 | /* | ||
| 345 | * Mark the last RDMA_READ with a bit to | ||
| 346 | * indicate all RPC data has been fetched from | ||
| 347 | * the client and the RPC needs to be enqueued. | ||
| 348 | */ | ||
| 349 | set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); | ||
| 350 | ctxt->next = hdr_ctxt; | ||
| 351 | hdr_ctxt->next = head; | ||
| 352 | } | ||
| 352 | /* Post the read */ | 353 | /* Post the read */ |
| 353 | err = svc_rdma_send(xprt, &read_wr); | 354 | err = svc_rdma_send(xprt, &read_wr); |
| 354 | if (err) { | 355 | if (err) { |
