123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- Glock internal locking rules
- ------------------------------
- This documents the basic principles of the glock state machine
- internals. Each glock (struct gfs2_glock in fs/gfs2/incore.h)
- has two main (internal) locks:
- 1. A spinlock (gl_lockref.lock) which protects the internal state such
- as gl_state, gl_target and the list of holders (gl_holders)
- 2. A non-blocking bit lock, GLF_LOCK, which is used to prevent other
- threads from making calls to the DLM, etc. at the same time. If a
- thread takes this lock, it must then call run_queue (usually via the
- workqueue) when it releases it in order to ensure any pending tasks
- are completed.
- The gl_holders list contains all the queued lock requests (not
- just the holders) associated with the glock. If there are any
- held locks, then they will be contiguous entries at the head
- of the list. Locks are granted in strictly the order that they
- are queued, except for those marked LM_FLAG_PRIORITY which are
- used only during recovery, and even then only for journal locks.
- There are three lock states that users of the glock layer can request,
- namely shared (SH), deferred (DF) and exclusive (EX). Those translate
- to the following DLM lock modes:
- Glock mode | DLM lock mode
- ------------------------------
- UN | IV/NL Unlocked (no DLM lock associated with glock) or NL
- SH | PR (Protected read)
- DF | CW (Concurrent write)
- EX | EX (Exclusive)
- Thus DF is basically a shared mode which is incompatible with the "normal"
- shared lock mode, SH. In GFS2 the DF mode is used exclusively for direct I/O
- operations. The glocks are basically a lock plus some routines which deal
- with cache management. The following rules apply for the cache:
- Glock mode | Cache data | Cache Metadata | Dirty Data | Dirty Metadata
- --------------------------------------------------------------------------
- UN | No | No | No | No
- SH | Yes | Yes | No | No
- DF | No | Yes | No | No
- EX | Yes | Yes | Yes | Yes
- These rules are implemented using the various glock operations which
- are defined for each type of glock. Not all types of glocks use
- all the modes. Only inode glocks use the DF mode for example.
- Table of glock operations and per type constants:
- Field | Purpose
- ----------------------------------------------------------------------------
- go_xmote_th | Called before remote state change (e.g. to sync dirty data)
- go_xmote_bh | Called after remote state change (e.g. to refill cache)
- go_inval | Called if remote state change requires invalidating the cache
- go_demote_ok | Returns boolean value of whether its ok to demote a glock
- | (e.g. checks timeout, and that there is no cached data)
- go_lock | Called for the first local holder of a lock
- go_unlock | Called on the final local unlock of a lock
- go_dump | Called to print content of object for debugfs file, or on
- | error to dump glock to the log.
- go_type | The type of the glock, LM_TYPE_.....
- go_callback | Called if the DLM sends a callback to drop this lock
- go_flags | GLOF_ASPACE is set, if the glock has an address space
- | associated with it
- The minimum hold time for each lock is the time after a remote lock
- grant for which we ignore remote demote requests. This is in order to
- prevent a situation where locks are being bounced around the cluster
- from node to node with none of the nodes making any progress. This
- tends to show up most with shared mmaped files which are being written
- to by multiple nodes. By delaying the demotion in response to a
- remote callback, that gives the userspace program time to make
- some progress before the pages are unmapped.
- There is a plan to try and remove the go_lock and go_unlock callbacks
- if possible, in order to try and speed up the fast path though the locking.
- Also, eventually we hope to make the glock "EX" mode locally shared
- such that any local locking will be done with the i_mutex as required
- rather than via the glock.
- Locking rules for glock operations:
- Operation | GLF_LOCK bit lock held | gl_lockref.lock spinlock held
- -------------------------------------------------------------------------
- go_xmote_th | Yes | No
- go_xmote_bh | Yes | No
- go_inval | Yes | No
- go_demote_ok | Sometimes | Yes
- go_lock | Yes | No
- go_unlock | Yes | No
- go_dump | Sometimes | Yes
- go_callback | Sometimes (N/A) | Yes
- N.B. Operations must not drop either the bit lock or the spinlock
- if its held on entry. go_dump and do_demote_ok must never block.
- Note that go_dump will only be called if the glock's state
- indicates that it is caching uptodate data.
- Glock locking order within GFS2:
- 1. i_mutex (if required)
- 2. Rename glock (for rename only)
- 3. Inode glock(s)
- (Parents before children, inodes at "same level" with same parent in
- lock number order)
- 4. Rgrp glock(s) (for (de)allocation operations)
- 5. Transaction glock (via gfs2_trans_begin) for non-read operations
- 6. Page lock (always last, very important!)
- There are two glocks per inode. One deals with access to the inode
- itself (locking order as above), and the other, known as the iopen
- glock is used in conjunction with the i_nlink field in the inode to
- determine the lifetime of the inode in question. Locking of inodes
- is on a per-inode basis. Locking of rgrps is on a per rgrp basis.
- In general we prefer to lock local locks prior to cluster locks.
- Glock Statistics
- ------------------
- The stats are divided into two sets: those relating to the
- super block and those relating to an individual glock. The
- super block stats are done on a per cpu basis in order to
- try and reduce the overhead of gathering them. They are also
- further divided by glock type. All timings are in nanoseconds.
- In the case of both the super block and glock statistics,
- the same information is gathered in each case. The super
- block timing statistics are used to provide default values for
- the glock timing statistics, so that newly created glocks
- should have, as far as possible, a sensible starting point.
- The per-glock counters are initialised to zero when the
- glock is created. The per-glock statistics are lost when
- the glock is ejected from memory.
- The statistics are divided into three pairs of mean and
- variance, plus two counters. The mean/variance pairs are
- smoothed exponential estimates and the algorithm used is
- one which will be very familiar to those used to calculation
- of round trip times in network code. See "TCP/IP Illustrated,
- Volume 1", W. Richard Stevens, sect 21.3, "Round-Trip Time Measurement",
- p. 299 and onwards. Also, Volume 2, Sect. 25.10, p. 838 and onwards.
- Unlike the TCP/IP Illustrated case, the mean and variance are
- not scaled, but are in units of integer nanoseconds.
- The three pairs of mean/variance measure the following
- things:
- 1. DLM lock time (non-blocking requests)
- 2. DLM lock time (blocking requests)
- 3. Inter-request time (again to the DLM)
- A non-blocking request is one which will complete right
- away, whatever the state of the DLM lock in question. That
- currently means any requests when (a) the current state of
- the lock is exclusive, i.e. a lock demotion (b) the requested
- state is either null or unlocked (again, a demotion) or (c) the
- "try lock" flag is set. A blocking request covers all the other
- lock requests.
- There are two counters. The first is there primarily to show
- how many lock requests have been made, and thus how much data
- has gone into the mean/variance calculations. The other counter
- is counting queuing of holders at the top layer of the glock
- code. Hopefully that number will be a lot larger than the number
- of dlm lock requests issued.
- So why gather these statistics? There are several reasons
- we'd like to get a better idea of these timings:
- 1. To be able to better set the glock "min hold time"
- 2. To spot performance issues more easily
- 3. To improve the algorithm for selecting resource groups for
- allocation (to base it on lock wait time, rather than blindly
- using a "try lock")
- Due to the smoothing action of the updates, a step change in
- some input quantity being sampled will only fully be taken
- into account after 8 samples (or 4 for the variance) and this
- needs to be carefully considered when interpreting the
- results.
- Knowing both the time it takes a lock request to complete and
- the average time between lock requests for a glock means we
- can compute the total percentage of the time for which the
- node is able to use a glock vs. time that the rest of the
- cluster has its share. That will be very useful when setting
- the lock min hold time.
- Great care has been taken to ensure that we
- measure exactly the quantities that we want, as accurately
- as possible. There are always inaccuracies in any
- measuring system, but I hope this is as accurate as we
- can reasonably make it.
- Per sb stats can be found here:
- /sys/kernel/debug/gfs2/<fsname>/sbstats
- Per glock stats can be found here:
- /sys/kernel/debug/gfs2/<fsname>/glstats
- Assuming that debugfs is mounted on /sys/kernel/debug and also
- that <fsname> is replaced with the name of the gfs2 filesystem
- in question.
- The abbreviations used in the output as are follows:
- srtt - Smoothed round trip time for non-blocking dlm requests
- srttvar - Variance estimate for srtt
- srttb - Smoothed round trip time for (potentially) blocking dlm requests
- srttvarb - Variance estimate for srttb
- sirt - Smoothed inter-request time (for dlm requests)
- sirtvar - Variance estimate for sirt
- dlm - Number of dlm requests made (dcnt in glstats file)
- queue - Number of glock requests queued (qcnt in glstats file)
- The sbstats file contains a set of these stats for each glock type (so 8 lines
- for each type) and for each cpu (one column per cpu). The glstats file contains
- a set of these stats for each glock in a similar format to the glocks file, but
- using the format mean/variance for each of the timing stats.
- The gfs2_glock_lock_time tracepoint prints out the current values of the stats
- for the glock in question, along with some addition information on each dlm
- reply that is received:
- status - The status of the dlm request
- flags - The dlm request flags
- tdiff - The time taken by this specific request
- (remaining fields as per above list)
|