Back to home page

OSCL-LXR

 
 

    


0001 Path walking and name lookup locking
0002 ====================================
0003 
0004 Path resolution is the finding a dentry corresponding to a path name string, by
0005 performing a path walk. Typically, for every open(), stat() etc., the path name
0006 will be resolved. Paths are resolved by walking the namespace tree, starting
0007 with the first component of the pathname (eg. root or cwd) with a known dentry,
0008 then finding the child of that dentry, which is named the next component in the
0009 path string. Then repeating the lookup from the child dentry and finding its
0010 child with the next element, and so on.
0011 
0012 Since it is a frequent operation for workloads like multiuser environments and
0013 web servers, it is important to optimize this code.
0014 
0015 Path walking synchronisation history:
0016 Prior to 2.5.10, dcache_lock was acquired in d_lookup (dcache hash lookup) and
0017 thus in every component during path look-up. Since 2.5.10 onwards, fast-walk
0018 algorithm changed this by holding the dcache_lock at the beginning and walking
0019 as many cached path component dentries as possible. This significantly
0020 decreases the number of acquisition of dcache_lock. However it also increases
0021 the lock hold time significantly and affects performance in large SMP machines.
0022 Since 2.5.62 kernel, dcache has been using a new locking model that uses RCU to
0023 make dcache look-up lock-free.
0024 
0025 All the above algorithms required taking a lock and reference count on the
0026 dentry that was looked up, so that may be used as the basis for walking the
0027 next path element. This is inefficient and unscalable. It is inefficient
0028 because of the locks and atomic operations required for every dentry element
0029 slows things down. It is not scalable because many parallel applications that
0030 are path-walk intensive tend to do path lookups starting from a common dentry
0031 (usually, the root "/" or current working directory). So contention on these
0032 common path elements causes lock and cacheline queueing.
0033 
0034 Since 2.6.38, RCU is used to make a significant part of the entire path walk
0035 (including dcache look-up) completely "store-free" (so, no locks, atomics, or
0036 even stores into cachelines of common dentries). This is known as "rcu-walk"
0037 path walking.
0038 
0039 Path walking overview
0040 =====================
0041 
0042 A name string specifies a start (root directory, cwd, fd-relative) and a
0043 sequence of elements (directory entry names), which together refer to a path in
0044 the namespace. A path is represented as a (dentry, vfsmount) tuple. The name
0045 elements are sub-strings, separated by '/'.
0046 
0047 Name lookups will want to find a particular path that a name string refers to
0048 (usually the final element, or parent of final element). This is done by taking
0049 the path given by the name's starting point (which we know in advance -- eg.
0050 current->fs->cwd or current->fs->root) as the first parent of the lookup. Then
0051 iteratively for each subsequent name element, look up the child of the current
0052 parent with the given name and if it is not the desired entry, make it the
0053 parent for the next lookup.
0054 
0055 A parent, of course, must be a directory, and we must have appropriate
0056 permissions on the parent inode to be able to walk into it.
0057 
0058 Turning the child into a parent for the next lookup requires more checks and
0059 procedures. Symlinks essentially substitute the symlink name for the target
0060 name in the name string, and require some recursive path walking.  Mount points
0061 must be followed into (thus changing the vfsmount that subsequent path elements
0062 refer to), switching from the mount point path to the root of the particular
0063 mounted vfsmount. These behaviours are variously modified depending on the
0064 exact path walking flags.
0065 
0066 Path walking then must, broadly, do several particular things:
0067 - find the start point of the walk;
0068 - perform permissions and validity checks on inodes;
0069 - perform dcache hash name lookups on (parent, name element) tuples;
0070 - traverse mount points;
0071 - traverse symlinks;
0072 - lookup and create missing parts of the path on demand.
0073 
0074 Safe store-free look-up of dcache hash table
0075 ============================================
0076 
0077 Dcache name lookup
0078 ------------------
0079 In order to lookup a dcache (parent, name) tuple, we take a hash on the tuple
0080 and use that to select a bucket in the dcache-hash table. The list of entries
0081 in that bucket is then walked, and we do a full comparison of each entry
0082 against our (parent, name) tuple.
0083 
0084 The hash lists are RCU protected, so list walking is not serialised with
0085 concurrent updates (insertion, deletion from the hash). This is a standard RCU
0086 list application with the exception of renames, which will be covered below.
0087 
0088 Parent and name members of a dentry, as well as its membership in the dcache
0089 hash, and its inode are protected by the per-dentry d_lock spinlock. A
0090 reference is taken on the dentry (while the fields are verified under d_lock),
0091 and this stabilises its d_inode pointer and actual inode. This gives a stable
0092 point to perform the next step of our path walk against.
0093 
0094 These members are also protected by d_seq seqlock, although this offers
0095 read-only protection and no durability of results, so care must be taken when
0096 using d_seq for synchronisation (see seqcount based lookups, below).
0097 
0098 Renames
0099 -------
0100 Back to the rename case. In usual RCU protected lists, the only operations that
0101 will happen to an object is insertion, and then eventually removal from the
0102 list. The object will not be reused until an RCU grace period is complete.
0103 This ensures the RCU list traversal primitives can run over the object without
0104 problems (see RCU documentation for how this works).
0105 
0106 However when a dentry is renamed, its hash value can change, requiring it to be
0107 moved to a new hash list. Allocating and inserting a new alias would be
0108 expensive and also problematic for directory dentries. Latency would be far to
0109 high to wait for a grace period after removing the dentry and before inserting
0110 it in the new hash bucket. So what is done is to insert the dentry into the
0111 new list immediately.
0112 
0113 However, when the dentry's list pointers are updated to point to objects in the
0114 new list before waiting for a grace period, this can result in a concurrent RCU
0115 lookup of the old list veering off into the new (incorrect) list and missing
0116 the remaining dentries on the list.
0117 
0118 There is no fundamental problem with walking down the wrong list, because the
0119 dentry comparisons will never match. However it is fatal to miss a matching
0120 dentry. So a seqlock is used to detect when a rename has occurred, and so the
0121 lookup can be retried.
0122 
0123          1      2      3
0124         +---+  +---+  +---+
0125 hlist-->| N-+->| N-+->| N-+->
0126 head <--+-P |<-+-P |<-+-P |
0127         +---+  +---+  +---+
0128 
0129 Rename of dentry 2 may require it deleted from the above list, and inserted
0130 into a new list. Deleting 2 gives the following list.
0131 
0132          1             3
0133         +---+         +---+     (don't worry, the longer pointers do not
0134 hlist-->| N-+-------->| N-+->    impose a measurable performance overhead
0135 head <--+-P |<--------+-P |      on modern CPUs)
0136         +---+         +---+
0137           ^      2      ^
0138           |    +---+    |
0139           |    | N-+----+
0140           +----+-P |
0141                +---+
0142 
0143 This is a standard RCU-list deletion, which leaves the deleted object's
0144 pointers intact, so a concurrent list walker that is currently looking at
0145 object 2 will correctly continue to object 3 when it is time to traverse the
0146 next object.
0147 
0148 However, when inserting object 2 onto a new list, we end up with this:
0149 
0150          1             3
0151         +---+         +---+
0152 hlist-->| N-+-------->| N-+->
0153 head <--+-P |<--------+-P |
0154         +---+         +---+
0155                  2
0156                +---+
0157                | N-+---->
0158           <----+-P |
0159                +---+
0160 
0161 Because we didn't wait for a grace period, there may be a concurrent lookup
0162 still at 2. Now when it follows 2's 'next' pointer, it will walk off into
0163 another list without ever having checked object 3.
0164 
0165 A related, but distinctly different, issue is that of rename atomicity versus
0166 lookup operations. If a file is renamed from 'A' to 'B', a lookup must only
0167 find either 'A' or 'B'. So if a lookup of 'A' returns NULL, a subsequent lookup
0168 of 'B' must succeed (note the reverse is not true).
0169 
0170 Between deleting the dentry from the old hash list, and inserting it on the new
0171 hash list, a lookup may find neither 'A' nor 'B' matching the dentry. The same
0172 rename seqlock is also used to cover this race in much the same way, by
0173 retrying a negative lookup result if a rename was in progress.
0174 
0175 Seqcount based lookups
0176 ----------------------
0177 In refcount based dcache lookups, d_lock is used to serialise access to
0178 the dentry, stabilising it while comparing its name and parent and then
0179 taking a reference count (the reference count then gives a stable place to
0180 start the next part of the path walk from).
0181 
0182 As explained above, we would like to do path walking without taking locks or
0183 reference counts on intermediate dentries along the path. To do this, a per
0184 dentry seqlock (d_seq) is used to take a "coherent snapshot" of what the dentry
0185 looks like (its name, parent, and inode). That snapshot is then used to start
0186 the next part of the path walk. When loading the coherent snapshot under d_seq,
0187 care must be taken to load the members up-front, and use those pointers rather
0188 than reloading from the dentry later on (otherwise we'd have interesting things
0189 like d_inode going NULL underneath us, if the name was unlinked).
0190 
0191 Also important is to avoid performing any destructive operations (pretty much:
0192 no non-atomic stores to shared data), and to recheck the seqcount when we are
0193 "done" with the operation. Retry or abort if the seqcount does not match.
0194 Avoiding destructive or changing operations means we can easily unwind from
0195 failure.
0196 
0197 What this means is that a caller, provided they are holding RCU lock to
0198 protect the dentry object from disappearing, can perform a seqcount based
0199 lookup which does not increment the refcount on the dentry or write to
0200 it in any way. This returned dentry can be used for subsequent operations,
0201 provided that d_seq is rechecked after that operation is complete.
0202 
0203 Inodes are also rcu freed, so the seqcount lookup dentry's inode may also be
0204 queried for permissions.
0205 
0206 With this two parts of the puzzle, we can do path lookups without taking
0207 locks or refcounts on dentry elements.
0208 
0209 RCU-walk path walking design
0210 ============================
0211 
0212 Path walking code now has two distinct modes, ref-walk and rcu-walk. ref-walk
0213 is the traditional[*] way of performing dcache lookups using d_lock to
0214 serialise concurrent modifications to the dentry and take a reference count on
0215 it. ref-walk is simple and obvious, and may sleep, take locks, etc while path
0216 walking is operating on each dentry. rcu-walk uses seqcount based dentry
0217 lookups, and can perform lookup of intermediate elements without any stores to
0218 shared data in the dentry or inode. rcu-walk can not be applied to all cases,
0219 eg. if the filesystem must sleep or perform non trivial operations, rcu-walk
0220 must be switched to ref-walk mode.
0221 
0222 [*] RCU is still used for the dentry hash lookup in ref-walk, but not the full
0223     path walk.
0224 
0225 Where ref-walk uses a stable, refcounted ``parent'' to walk the remaining
0226 path string, rcu-walk uses a d_seq protected snapshot. When looking up a
0227 child of this parent snapshot, we open d_seq critical section on the child
0228 before closing d_seq critical section on the parent. This gives an interlocking
0229 ladder of snapshots to walk down.
0230 
0231 
0232      proc 101
0233       /----------------\
0234      / comm:    "vi"    \
0235     /  fs.root: dentry0  \
0236     \  fs.cwd:  dentry2  /
0237      \                  /
0238       \----------------/
0239 
0240 So when vi wants to open("/home/npiggin/test.c", O_RDWR), then it will
0241 start from current->fs->root, which is a pinned dentry. Alternatively,
0242 "./test.c" would start from cwd; both names refer to the same path in
0243 the context of proc101.
0244 
0245      dentry 0
0246     +---------------------+   rcu-walk begins here, we note d_seq, check the
0247     | name:    "/"        |   inode's permission, and then look up the next
0248     | inode:   10         |   path element which is "home"...
0249     | children:"home", ...|
0250     +---------------------+
0251               |
0252      dentry 1 V
0253     +---------------------+   ... which brings us here. We find dentry1 via
0254     | name:    "home"     |   hash lookup, then note d_seq and compare name
0255     | inode:   678        |   string and parent pointer. When we have a match,
0256     | children:"npiggin"  |   we now recheck the d_seq of dentry0. Then we
0257     +---------------------+   check inode and look up the next element.
0258               |
0259      dentry2  V
0260     +---------------------+   Note: if dentry0 is now modified, lookup is
0261     | name:    "npiggin"  |   not necessarily invalid, so we need only keep a
0262     | inode:   543        |   parent for d_seq verification, and grandparents
0263     | children:"a.c", ... |   can be forgotten.
0264     +---------------------+
0265               |
0266      dentry3  V
0267     +---------------------+   At this point we have our destination dentry.
0268     | name:    "a.c"      |   We now take its d_lock, verify d_seq of this
0269     | inode:   14221      |   dentry. If that checks out, we can increment
0270     | children:NULL       |   its refcount because we're holding d_lock.
0271     +---------------------+
0272 
0273 Taking a refcount on a dentry from rcu-walk mode, by taking its d_lock,
0274 re-checking its d_seq, and then incrementing its refcount is called
0275 "dropping rcu" or dropping from rcu-walk into ref-walk mode.
0276 
0277 It is, in some sense, a bit of a house of cards. If the seqcount check of the
0278 parent snapshot fails, the house comes down, because we had closed the d_seq
0279 section on the grandparent, so we have nothing left to stand on. In that case,
0280 the path walk must be fully restarted (which we do in ref-walk mode, to avoid
0281 live locks). It is costly to have a full restart, but fortunately they are
0282 quite rare.
0283 
0284 When we reach a point where sleeping is required, or a filesystem callout
0285 requires ref-walk, then instead of restarting the walk, we attempt to drop rcu
0286 at the last known good dentry we have. Avoiding a full restart in ref-walk in
0287 these cases is fundamental for performance and scalability because blocking
0288 operations such as creates and unlinks are not uncommon.
0289 
0290 The detailed design for rcu-walk is like this:
0291 * LOOKUP_RCU is set in nd->flags, which distinguishes rcu-walk from ref-walk.
0292 * Take the RCU lock for the entire path walk, starting with the acquiring
0293   of the starting path (eg. root/cwd/fd-path). So now dentry refcounts are
0294   not required for dentry persistence.
0295 * synchronize_rcu is called when unregistering a filesystem, so we can
0296   access d_ops and i_ops during rcu-walk.
0297 * Similarly take the vfsmount lock for the entire path walk. So now mnt
0298   refcounts are not required for persistence. Also we are free to perform mount
0299   lookups, and to assume dentry mount points and mount roots are stable up and
0300   down the path.
0301 * Have a per-dentry seqlock to protect the dentry name, parent, and inode,
0302   so we can load this tuple atomically, and also check whether any of its
0303   members have changed.
0304 * Dentry lookups (based on parent, candidate string tuple) recheck the parent
0305   sequence after the child is found in case anything changed in the parent
0306   during the path walk.
0307 * inode is also RCU protected so we can load d_inode and use the inode for
0308   limited things.
0309 * i_mode, i_uid, i_gid can be tested for exec permissions during path walk.
0310 * i_op can be loaded.
0311 * When the destination dentry is reached, drop rcu there (ie. take d_lock,
0312   verify d_seq, increment refcount).
0313 * If seqlock verification fails anywhere along the path, do a full restart
0314   of the path lookup in ref-walk mode. -ECHILD tends to be used (for want of
0315   a better errno) to signal an rcu-walk failure.
0316 
0317 The cases where rcu-walk cannot continue are:
0318 * NULL dentry (ie. any uncached path element)
0319 * Following links
0320 
0321 It may be possible eventually to make following links rcu-walk aware.
0322 
0323 Uncached path elements will always require dropping to ref-walk mode, at the
0324 very least because i_mutex needs to be grabbed, and objects allocated.
0325 
0326 Final note:
0327 "store-free" path walking is not strictly store free. We take vfsmount lock
0328 and refcounts (both of which can be made per-cpu), and we also store to the
0329 stack (which is essentially CPU-local), and we also have to take locks and
0330 refcount on final dentry.
0331 
0332 The point is that shared data, where practically possible, is not locked
0333 or stored into. The result is massive improvements in performance and
0334 scalability of path resolution.
0335 
0336 
0337 Interesting statistics
0338 ======================
0339 
0340 The following table gives rcu lookup statistics for a few simple workloads
0341 (2s12c24t Westmere, debian non-graphical system). Ungraceful are attempts to
0342 drop rcu that fail due to d_seq failure and requiring the entire path lookup
0343 again. Other cases are successful rcu-drops that are required before the final
0344 element, nodentry for missing dentry, revalidate for filesystem revalidate
0345 routine requiring rcu drop, permission for permission check requiring drop,
0346 and link for symlink traversal requiring drop.
0347 
0348      rcu-lookups     restart  nodentry          link  revalidate  permission
0349 bootup     47121           0      4624          1010       10283        7852
0350 dbench  25386793           0   6778659(26.7%)     55         549        1156
0351 kbuild   2696672          10     64442(2.3%)  108764(4.0%)     1        1590
0352 git diff   39605           0        28             2           0         106
0353 vfstest 24185492        4945    708725(2.9%) 1076136(4.4%)     0        2651
0354 
0355 What this shows is that failed rcu-walk lookups, ie. ones that are restarted
0356 entirely with ref-walk, are quite rare. Even the "vfstest" case which
0357 specifically has concurrent renames/mkdir/rmdir/ creat/unlink/etc to exercise
0358 such races is not showing a huge amount of restarts.
0359 
0360 Dropping from rcu-walk to ref-walk mean that we have encountered a dentry where
0361 the reference count needs to be taken for some reason. This is either because
0362 we have reached the target of the path walk, or because we have encountered a
0363 condition that can't be resolved in rcu-walk mode.  Ideally, we drop rcu-walk
0364 only when we have reached the target dentry, so the other statistics show where
0365 this does not happen.
0366 
0367 Note that a graceful drop from rcu-walk mode due to something such as the
0368 dentry not existing (which can be common) is not necessarily a failure of
0369 rcu-walk scheme, because some elements of the path may have been walked in
0370 rcu-walk mode. The further we get from common path elements (such as cwd or
0371 root), the less contended the dentry is likely to be. The closer we are to
0372 common path elements, the more likely they will exist in dentry cache.
0373 
0374 
0375 Papers and other documentation on dcache locking
0376 ================================================
0377 
0378 1. Scaling dcache with RCU (https://linuxjournal.com/article.php?sid=7124).
0379 
0380 2. http://lse.sourceforge.net/locking/dcache/dcache.html
0381 
0382 3. path-lookup.md in this directory.