diff options
Diffstat (limited to 'kernel/rcupdate.c')
-rw-r--r-- | kernel/rcupdate.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index bef3b6901b76..c4d159a21e04 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -71,7 +71,7 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L }; | |||
71 | 71 | ||
72 | /* Fake initialization required by compiler */ | 72 | /* Fake initialization required by compiler */ |
73 | static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; | 73 | static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; |
74 | static int maxbatch = 10; | 74 | static int maxbatch = 10000; |
75 | 75 | ||
76 | #ifndef __HAVE_ARCH_CMPXCHG | 76 | #ifndef __HAVE_ARCH_CMPXCHG |
77 | /* | 77 | /* |
@@ -109,6 +109,10 @@ void fastcall call_rcu(struct rcu_head *head, | |||
109 | rdp = &__get_cpu_var(rcu_data); | 109 | rdp = &__get_cpu_var(rcu_data); |
110 | *rdp->nxttail = head; | 110 | *rdp->nxttail = head; |
111 | rdp->nxttail = &head->next; | 111 | rdp->nxttail = &head->next; |
112 | |||
113 | if (unlikely(++rdp->count > 10000)) | ||
114 | set_need_resched(); | ||
115 | |||
112 | local_irq_restore(flags); | 116 | local_irq_restore(flags); |
113 | } | 117 | } |
114 | 118 | ||
@@ -140,10 +144,25 @@ void fastcall call_rcu_bh(struct rcu_head *head, | |||
140 | rdp = &__get_cpu_var(rcu_bh_data); | 144 | rdp = &__get_cpu_var(rcu_bh_data); |
141 | *rdp->nxttail = head; | 145 | *rdp->nxttail = head; |
142 | rdp->nxttail = &head->next; | 146 | rdp->nxttail = &head->next; |
147 | rdp->count++; | ||
148 | /* | ||
149 | * Should we directly call rcu_do_batch() here ? | ||
150 | * if (unlikely(rdp->count > 10000)) | ||
151 | * rcu_do_batch(rdp); | ||
152 | */ | ||
143 | local_irq_restore(flags); | 153 | local_irq_restore(flags); |
144 | } | 154 | } |
145 | 155 | ||
146 | /* | 156 | /* |
157 | * Return the number of RCU batches processed thus far. Useful | ||
158 | * for debug and statistics. | ||
159 | */ | ||
160 | long rcu_batches_completed(void) | ||
161 | { | ||
162 | return rcu_ctrlblk.completed; | ||
163 | } | ||
164 | |||
165 | /* | ||
147 | * Invoke the completed RCU callbacks. They are expected to be in | 166 | * Invoke the completed RCU callbacks. They are expected to be in |
148 | * a per-cpu list. | 167 | * a per-cpu list. |
149 | */ | 168 | */ |
@@ -157,6 +176,7 @@ static void rcu_do_batch(struct rcu_data *rdp) | |||
157 | next = rdp->donelist = list->next; | 176 | next = rdp->donelist = list->next; |
158 | list->func(list); | 177 | list->func(list); |
159 | list = next; | 178 | list = next; |
179 | rdp->count--; | ||
160 | if (++count >= maxbatch) | 180 | if (++count >= maxbatch) |
161 | break; | 181 | break; |
162 | } | 182 | } |
@@ -490,6 +510,7 @@ void synchronize_kernel(void) | |||
490 | } | 510 | } |
491 | 511 | ||
492 | module_param(maxbatch, int, 0); | 512 | module_param(maxbatch, int, 0); |
513 | EXPORT_SYMBOL_GPL(rcu_batches_completed); | ||
493 | EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */ | 514 | EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */ |
494 | EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */ | 515 | EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */ |
495 | EXPORT_SYMBOL_GPL(synchronize_rcu); | 516 | EXPORT_SYMBOL_GPL(synchronize_rcu); |