aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-06-23 18:50:06 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-06-23 18:50:06 -0700
commitb659a6fbb927a79acd606c4466d03cb615879f9f (patch)
tree3a41b7176af74b5828a24711859723d04f5b1f29 /kernel
parent72914d307d2ab4630212644a46cf75746d04440d (diff)
downloadhistory-b659a6fbb927a79acd606c4466d03cb615879f9f.tar.gz
[PATCH] reduce rcu_head size - core
From: Dipankar Sarma <dipankar@in.ibm.com> This reduces the RCU head size by using a singly linked to maintain them. The ordering of the callbacks is still maintained as before by using a tail pointer for the next list. Signed-Off-By : Dipankar Sarma <dipankar@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/rcupdate.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 0e13bdbb9fd730..cdb59f12a5fa92 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -82,9 +82,11 @@ void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg
head->func = func;
head->arg = arg;
+ head->next = NULL;
local_irq_save(flags);
cpu = smp_processor_id();
- list_add_tail(&head->list, &RCU_nxtlist(cpu));
+ *RCU_nxttail(cpu) = head;
+ RCU_nxttail(cpu) = &head->next;
local_irq_restore(flags);
}
@@ -92,16 +94,14 @@ void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg
* Invoke the completed RCU callbacks. They are expected to be in
* a per-cpu list.
*/
-static void rcu_do_batch(struct list_head *list)
+static void rcu_do_batch(struct rcu_head *list)
{
- struct list_head *entry;
- struct rcu_head *head;
+ struct rcu_head *next;
- while (!list_empty(list)) {
- entry = list->next;
- list_del(entry);
- head = list_entry(entry, struct rcu_head, list);
- head->func(head->arg);
+ while (list) {
+ next = list->next;
+ list->func(list->arg);
+ list = next;
}
}
@@ -262,20 +262,21 @@ void rcu_restart_cpu(int cpu)
static void rcu_process_callbacks(unsigned long unused)
{
int cpu = smp_processor_id();
- LIST_HEAD(list);
+ struct rcu_head *rcu_list = NULL;
- if (!list_empty(&RCU_curlist(cpu)) &&
- !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) {
- __list_splice(&RCU_curlist(cpu), &list);
- INIT_LIST_HEAD(&RCU_curlist(cpu));
+ if (RCU_curlist(cpu) &&
+ !rcu_batch_before(rcu_ctrlblk.completed, RCU_batch(cpu))) {
+ rcu_list = RCU_curlist(cpu);
+ RCU_curlist(cpu) = NULL;
}
local_irq_disable();
- if (!list_empty(&RCU_nxtlist(cpu)) && list_empty(&RCU_curlist(cpu))) {
+ if (RCU_nxtlist(cpu) && !RCU_curlist(cpu)) {
int next_pending, seq;
- __list_splice(&RCU_nxtlist(cpu), &RCU_curlist(cpu));
- INIT_LIST_HEAD(&RCU_nxtlist(cpu));
+ RCU_curlist(cpu) = RCU_nxtlist(cpu);
+ RCU_nxtlist(cpu) = NULL;
+ RCU_nxttail(cpu) = &RCU_nxtlist(cpu);
local_irq_enable();
/*
@@ -298,8 +299,8 @@ static void rcu_process_callbacks(unsigned long unused)
local_irq_enable();
}
rcu_check_quiescent_state();
- if (!list_empty(&list))
- rcu_do_batch(&list);
+ if (rcu_list)
+ rcu_do_batch(rcu_list);
}
void rcu_check_callbacks(int cpu, int user)
@@ -315,8 +316,7 @@ static void __devinit rcu_online_cpu(int cpu)
{
memset(&per_cpu(rcu_data, cpu), 0, sizeof(struct rcu_data));
tasklet_init(&RCU_tasklet(cpu), rcu_process_callbacks, 0UL);
- INIT_LIST_HEAD(&RCU_nxtlist(cpu));
- INIT_LIST_HEAD(&RCU_curlist(cpu));
+ RCU_nxttail(cpu) = &RCU_nxtlist(cpu);
RCU_quiescbatch(cpu) = rcu_ctrlblk.completed;
RCU_qs_pending(cpu) = 0;
}