diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2005-10-17 14:01:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-17 18:27:58 -0400 |
commit | 5ee832dbc6770135ec8d63296af0a4374557bb79 (patch) | |
tree | 80ffdc157100df18f1c18d39f5036a9b798f2c06 | |
parent | cc675230a9ca17010694bc8bd3c69ca9adf2efef (diff) |
[PATCH] rcu: keep rcu callback event counter
This makes call_rcu() keep track of how many events there are on the RCU
list, and cause a reschedule event when the list gets too long.
This helps keep RCU event lists down.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | include/linux/rcupdate.h | 1 | ||||
-rw-r--r-- | kernel/rcupdate.c | 11 |
2 files changed, 12 insertions, 0 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 4e65eb44adfd..70191a5a148f 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -94,6 +94,7 @@ struct rcu_data { | |||
94 | long batch; /* Batch # for current RCU batch */ | 94 | long batch; /* Batch # for current RCU batch */ |
95 | struct rcu_head *nxtlist; | 95 | struct rcu_head *nxtlist; |
96 | struct rcu_head **nxttail; | 96 | struct rcu_head **nxttail; |
97 | long count; /* # of queued items */ | ||
97 | struct rcu_head *curlist; | 98 | struct rcu_head *curlist; |
98 | struct rcu_head **curtail; | 99 | struct rcu_head **curtail; |
99 | struct rcu_head *donelist; | 100 | struct rcu_head *donelist; |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index dd99415b1551..2559d4b8f23f 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -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,6 +144,12 @@ 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 | ||
@@ -157,6 +167,7 @@ static void rcu_do_batch(struct rcu_data *rdp) | |||
157 | next = rdp->donelist = list->next; | 167 | next = rdp->donelist = list->next; |
158 | list->func(list); | 168 | list->func(list); |
159 | list = next; | 169 | list = next; |
170 | rdp->count--; | ||
160 | if (++count >= maxbatch) | 171 | if (++count >= maxbatch) |
161 | break; | 172 | break; |
162 | } | 173 | } |