lkml.org 
[lkml]   [2013]   [Sep]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [RFC] introduce synchronize_sched_{enter,exit}()
    On Mon, Sep 30, 2013 at 02:59:42PM +0200, Peter Zijlstra wrote:

    > >
    > > static void cb_rcu_func(struct rcu_head *rcu)
    > > {
    > > struct xxx_struct *xxx = container_of(rcu, struct xxx_struct, cb_head);
    > > long flags;
    > >
    > > BUG_ON(xxx->gp_state != GP_PASSED);
    > > BUG_ON(xxx->cb_state == CB_IDLE);
    > >
    > > spin_lock_irqsave(&xxx->xxx_lock, flags);
    > > if (xxx->gp_count) {
    > > xxx->cb_state = CB_IDLE;
    >
    > This seems to be when a new xxx_begin() has happened after our last
    > xxx_end() and the sync_sched() from xxx_begin() merges with the
    > xxx_end() one and we're done.
    >
    > > } else if (xxx->cb_state == CB_REPLAY) {
    > > xxx->cb_state = CB_PENDING;
    > > call_rcu_sched(&xxx->cb_head, cb_rcu_func);
    >
    > A later xxx_exit() has happened, and we need to requeue to catch a later
    > GP.
    >
    > > } else {
    > > xxx->cb_state = CB_IDLE;
    > > xxx->gp_state = GP_IDLE;
    >
    > Nothing fancy happened and we're done.
    >
    > > }
    > > spin_unlock_irqrestore(&xxx->xxx_lock, flags);
    > > }
    > >
    > > void xxx_exit(struct xxx_struct *xxx)
    > > {
    > > spin_lock_irq(&xxx->xxx_lock);
    > > if (!--xxx->gp_count) {
    > > if (xxx->cb_state == CB_IDLE) {
    > > xxx->cb_state = CB_PENDING;
    > > call_rcu_sched(&xxx->cb_head, cb_rcu_func);
    > > } else if (xxx->cb_state == CB_PENDING) {
    > > xxx->cb_state = CB_REPLAY;
    > > }
    > > }
    > > spin_unlock_irq(&xxx->xxx_lock);
    > > }
    >
    > So I don't immediately see the point of the concurrent write side;
    > percpu_rwsem wouldn't allow this and afaict neither would
    > freeze_super().
    >
    > Other than that; yes this makes sense if you care about write side
    > performance and I think its solid.

    Hmm, wait. I don't see how this is equivalent to:

    xxx_end()
    {
    synchronize_sched();
    atomic_dec(&xxx->counter);
    }

    For that we'd have to decrement xxx->gp_count from cb_rcu_func(),
    wouldn't we?

    Without that there's no guarantee the fast path readers will have a MB
    to observe the write critical section, unless I'm completely missing
    something obviuos here.


    \
     
     \ /
      Last update: 2013-09-30 18:01    [W:3.086 / U:0.668 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site