Re: [RFC,PATCH] Use RCU to protect tasklist for unicast signals

From: Ingo Molnar
Date: Thu Aug 11 2005 - 04:56:38 EST



* Paul E. McKenney <paulmck@xxxxxxxxxx> wrote:

> Hello!
>
> This patch is an experiment in use of RCU for individual code paths
> that read-acquire the tasklist lock, in this case, unicast signal
> delivery. It passes five kernbenches on 4-CPU x86, but obviously needs
> much more testing before it is considered for serious use, let alone
> inclusion.
>
> My main question is whether I have the POSIX semantics covered. I
> believe that I do, but thought I should check with people who are more
> familiar with POSIX than am I.
>
> For the record, some shortcomings of this patch:
>
> o Needs lots more testing on more architectures.
>
> o Needs performance and stress testing.
>
> o Needs testing in Ingo's PREEMPT_RT environment.

cool patch! I have integrated it into my PREEMPT_RT tree, and all it
needed to boot was the patch below (doesnt affect the upstream kernel).
Using the raw IRQ flag isnt an issue in the RCU code, all the affected
codepaths are small and deterministic.

(without this patch it locked up after detecting IRQ7 - not sure why.)

kernel still works fine after some (mostly light) testing.

Ingo

Index: linux/kernel/rcupdate.c
===================================================================
--- linux.orig/kernel/rcupdate.c
+++ linux/kernel/rcupdate.c
@@ -134,11 +134,11 @@ void fastcall call_rcu(struct rcu_head *

head->func = func;
head->next = NULL;
- local_irq_save(flags);
+ raw_local_irq_save(flags);
rdp = &__get_cpu_var(rcu_data);
*rdp->nxttail = head;
rdp->nxttail = &head->next;
- local_irq_restore(flags);
+ raw_local_irq_restore(flags);
}

/**
@@ -165,11 +165,11 @@ void fastcall call_rcu_bh(struct rcu_hea

head->func = func;
head->next = NULL;
- local_irq_save(flags);
+ raw_local_irq_save(flags);
rdp = &__get_cpu_var(rcu_bh_data);
*rdp->nxttail = head;
rdp->nxttail = &head->next;
- local_irq_restore(flags);
+ raw_local_irq_restore(flags);
}

/*
@@ -305,11 +305,11 @@ static void rcu_check_quiescent_state(st
static void rcu_move_batch(struct rcu_data *this_rdp, struct rcu_head *list,
struct rcu_head **tail)
{
- local_irq_disable();
+ raw_local_irq_disable();
*this_rdp->nxttail = list;
if (list)
this_rdp->nxttail = tail;
- local_irq_enable();
+ raw_local_irq_enable();
}

static void __rcu_offline_cpu(struct rcu_data *this_rdp,
@@ -362,13 +362,13 @@ static void __rcu_process_callbacks(stru
rdp->curtail = &rdp->curlist;
}

- local_irq_disable();
+ raw_local_irq_disable();
if (rdp->nxtlist && !rdp->curlist) {
rdp->curlist = rdp->nxtlist;
rdp->curtail = rdp->nxttail;
rdp->nxtlist = NULL;
rdp->nxttail = &rdp->nxtlist;
- local_irq_enable();
+ raw_local_irq_enable();

/*
* start the next batch of callbacks
@@ -388,7 +388,7 @@ static void __rcu_process_callbacks(stru
spin_unlock(&rsp->lock);
}
} else {
- local_irq_enable();
+ raw_local_irq_enable();
}
rcu_check_quiescent_state(rcp, rsp, rdp);
if (rdp->donelist)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/