aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet2005-10-17 20:01:21 +0200
committerLinus Torvalds2005-10-17 15:27:58 -0700
commit5ee832dbc6770135ec8d63296af0a4374557bb79 (patch)
tree80ffdc157100df18f1c18d39f5036a9b798f2c06
parentcc675230a9ca17010694bc8bd3c69ca9adf2efef (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.h1
-rw-r--r--kernel/rcupdate.c11
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 {
long batch; /* Batch # for current RCU batch */
struct rcu_head *nxtlist;
struct rcu_head **nxttail;
+ long count; /* # of queued items */
struct rcu_head *curlist;
struct rcu_head **curtail;
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,
rdp = &__get_cpu_var(rcu_data);
*rdp->nxttail = head;
rdp->nxttail = &head->next;
+
+ if (unlikely(++rdp->count > 10000))
+ set_need_resched();
+
local_irq_restore(flags);
}
@@ -140,6 +144,12 @@ void fastcall call_rcu_bh(struct rcu_head *head,
rdp = &__get_cpu_var(rcu_bh_data);
*rdp->nxttail = head;
rdp->nxttail = &head->next;
+ rdp->count++;
+/*
+ * Should we directly call rcu_do_batch() here ?
+ * if (unlikely(rdp->count > 10000))
+ * rcu_do_batch(rdp);
+ */
local_irq_restore(flags);
}
@@ -157,6 +167,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
next = rdp->donelist = list->next;
list->func(list);
list = next;
+ rdp->count--;
if (++count >= maxbatch)
break;
}