Re: [RFC PATCH 2/6] Preempt-RCU: Reorganize RCU code into rcuclassic.c and rcupdate.c

From: Paul E. McKenney
Date: Fri Dec 14 2007 - 11:13:31 EST


On Fri, Dec 14, 2007 at 03:51:14PM +0100, Johannes Weiner wrote:
> Hi,
>
> Gautham R Shenoy <ego@xxxxxxxxxx> writes:
>
> > diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c
> > new file mode 100644
> > index 0000000..11c16aa
> > --- /dev/null
> > +++ b/kernel/rcuclassic.c
> > +/**
> > + * call_rcu - Queue an RCU callback for invocation after a grace period.
> > + * @head: structure to be used for queueing the RCU updates.
> > + * @func: actual update function to be invoked after the grace period
> > + *
> > + * The update function will be invoked some time after a full grace
> > + * period elapses, in other words after all currently executing RCU
> > + * read-side critical sections have completed. RCU read-side critical
> > + * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
> > + * and may be nested.
> > + */
> > +void call_rcu(struct rcu_head *head,
> > + void (*func)(struct rcu_head *rcu))
> > +{
> > + unsigned long flags;
> > + struct rcu_data *rdp;
> > +
> > + head->func = func;
> > + head->next = NULL;
> > + local_irq_save(flags);
> > + rdp = &__get_cpu_var(rcu_data);
> > + *rdp->nxttail = head;
> > + rdp->nxttail = &head->next;
> > + if (unlikely(++rdp->qlen > qhimark)) {
> > + rdp->blimit = INT_MAX;
> > + force_quiescent_state(rdp, &rcu_ctrlblk);
> > + }
> > + local_irq_restore(flags);
> > +}
> > +EXPORT_SYMBOL_GPL(call_rcu);
> > +
> > +/**
> > + * call_rcu_bh - Queue an RCU for invocation after a quicker grace period.
> > + * @head: structure to be used for queueing the RCU updates.
> > + * @func: actual update function to be invoked after the grace period
> > + *
> > + * The update function will be invoked some time after a full grace
> > + * period elapses, in other words after all currently executing RCU
> > + * read-side critical sections have completed. call_rcu_bh() assumes
> > + * that the read-side critical sections end on completion of a softirq
> > + * handler. This means that read-side critical sections in process
> > + * context must not be interrupted by softirqs. This interface is to be
> > + * used when most of the read-side critical sections are in softirq context.
> > + * RCU read-side critical sections are delimited by rcu_read_lock() and
> > + * rcu_read_unlock(), * if in interrupt context or rcu_read_lock_bh()
> > + * and rcu_read_unlock_bh(), if in process context. These may be nested.
> > + */
> > +void call_rcu_bh(struct rcu_head *head,
> > + void (*func)(struct rcu_head *rcu))
> > +{
> > + unsigned long flags;
> > + struct rcu_data *rdp;
> > +
> > + head->func = func;
> > + head->next = NULL;
> > + local_irq_save(flags);
> > + rdp = &__get_cpu_var(rcu_bh_data);
> > + *rdp->nxttail = head;
> > + rdp->nxttail = &head->next;
> > +
> > + if (unlikely(++rdp->qlen > qhimark)) {
> > + rdp->blimit = INT_MAX;
> > + force_quiescent_state(rdp, &rcu_bh_ctrlblk);
> > + }
> > +
> > + local_irq_restore(flags);
> > +}
> > +EXPORT_SYMBOL_GPL(call_rcu_bh);
>
> Those two functions are identical beside the difference of `rcu_data'
> <-> `rcu_bh_data' and `rcu_ctrlblk' <-> `rcu_bh_ctrlblk'.
>
> Is there a way to collapse the code into one helper function or would
> that effect performance too much?

This code is performance critical, but on the other hand, perhaps gcc
has gotten smarter in the years since this was written. (This patch is
just moving this code from one file to another, rather than writing it
from scratch.) Would current gcc implementations be able to do the
inlining required?

Thanx, Paul
--
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/