10.07.2015 Views

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

184 APPENDIX D. READ-COPY UPDATE IMPLEMENTATIONSwithin Classic RCU read-side critical sections?Quick Quiz D.2: Why not permit sleeping inClassic RCU read-side critical sections by eliminatingcontext switch as a quiescent state, leaving usermodeexecution and idle loop as the remaining quiescentstates?D.1.1 SRCU Implementation StrategyThe primary challenge in designing an SRCU is toprevent any given task sleeping in an RCU read-sidecritical section from blocking an unbounded numberof RCU callbacks. SRCU uses two strategies toachieve this goal:1. refusing to provide asynchronous grace-periodinterfaces, such as the Classic RCU’s call_rcu() API, and2. isolating grace-period detection within eachsubsystem using SRCU.The rationale for these strategies are discussed inthe following sections.D.1.1.1 Abolish Asynchronous Grace-Period AP<strong>Is</strong>The problem with the call_rcu() API is that asingle thread can generate an arbitrarily large numberof blocks of memory awaiting a grace period, asillustrated by the following:1 while (p = kmalloc(sizeof(*p), GFP_ATOMIC))2 call_rcu(&p->rcu, f);In contrast, the analogous code usingsynchronize_rcu() can have at most a singleblock of memory per thread awaiting a graceperiod:1 while (p = kmalloc(sizeof(*p),2 GFP_ATOMIC)) {3 synchronize_rcu();4 kfree(&p->rcu, f);5 }Therefore, SRCU provides an equivalent tosynchronize_rcu(), but not to call_rcu().D.1.1.2 <strong>Is</strong>olate Grace-Period DetectionIn Classic RCU, a single read-side critical sectioncould indefinitely delay all RCU callbacks, for example,as follows:1 /* BUGGY: <strong>Do</strong> not use!!! */2 rcu_read_lock();3 schedule_timeout_interruptible(longdelay);4 rcu_read_unlock();This sort of behavior might be tolerated if RCUwere used only within a single subsystem that wascarefully designed to withstand long-term delay ofgrace periods. <strong>It</strong> is the fact that a single RCU readsidebuginoneisolatedsubsystemcandelayallusersof RCU that forced these long-term RCU read-sidedelays to be abolished.One way around this issue is for grace-perioddetection to be performed on a subsystem-bysubsystembasis, so that a lethargic RCU readerwill delay grace periods only within that reader’ssubsystem. Since each subsystem can have only abounded number of memory blocks awaiting a graceperiod, and since the number of subsystems is alsopresumably bounded, the total amount of memoryawaiting a grace period will also be bounded. Thedesigner of a given subsystem is responsible for: (1)ensuring that SRCU read-side sleeping is boundedand (2) limiting the amount of memory waiting forsynchronize_srcu(). 1This is precisely the approach that SRCU takes,as described in the following section.D.1.2 SRCU API and UsageThe SRCU API is shown in Figure D.2. The followingsections describe how to use it.int init_srcu_struct(struct srcu_struct *sp);void cleanup_srcu_struct(struct srcu_struct *sp);int srcu_read_lock(struct srcu_struct *sp);void srcu_read_unlock(struct srcu_struct *sp, int idx);void synchronize_srcu(struct srcu_struct *sp);long srcu_batches_completed(struct srcu_struct *sp);Figure D.2: SRCU APID.1.2.1 Initialization and CleanupEach subsystem using SRCU must create an structsrcu_struct, either by declaring a variable of thistype or by dynamically allocating the memory, forexample, via kmalloc(). Once this structure isin place, it must be initialized via init_srcu_struct(), which returns zero for success or an errorcode for failure (for example, upon memory exhaustion).1 For example, an SRCU-protected hash table might havea lock per hash chain, thus allowing at most one block perhash chain to be waiting for synchronize_srcu().

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!