1. 23 7月, 2010 1 次提交
    • T
      fscache: convert object to use workqueue instead of slow-work · 8b8edefa
      Tejun Heo 提交于
      Make fscache object state transition callbacks use workqueue instead
      of slow-work.  New dedicated unbound CPU workqueue fscache_object_wq
      is created.  get/put callbacks are renamed and modified to take
      @object and called directly from the enqueue wrapper and the work
      function.  While at it, make all open coded instances of get/put to
      use fscache_get/put_object().
      
      * Unbound workqueue is used.
      
      * work_busy() output is printed instead of slow-work flags in object
        debugging outputs.  They mean basically the same thing bit-for-bit.
      
      * sysctl fscache.object_max_active added to control concurrency.  The
        default value is nr_cpus clamped between 4 and
        WQ_UNBOUND_MAX_ACTIVE.
      
      * slow_work_sleep_till_thread_needed() is replaced with fscache
        private implementation fscache_object_sleep_till_congested() which
        waits on fscache_object_wq congestion.
      
      * debugfs support is dropped for now.  Tracing API based debug
        facility is planned to be added.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Acked-by: NDavid Howells <dhowells@redhat.com>
      8b8edefa
  2. 30 3月, 2010 1 次提交
  3. 20 11月, 2009 9 次提交
    • D
      CacheFiles: Catch an overly long wait for an old active object · fee096de
      David Howells 提交于
      Catch an overly long wait for an old, dying active object when we want to
      replace it with a new one.  The probability is that all the slow-work threads
      are hogged, and the delete can't get a look in.
      
      What we do instead is:
      
       (1) if there's nothing in the slow work queue, we sleep until either the dying
           object has finished dying or there is something in the slow work queue
           behind which we can queue our object.
      
       (2) if there is something in the slow work queue, we return ETIMEDOUT to
           fscache_lookup_object(), which then puts us back on the slow work queue,
           presumably behind the deletion that we're blocked by.  We are then
           deferred for a while until we work our way back through the queue -
           without blocking a slow-work thread unnecessarily.
      
      A backtrace similar to the following may appear in the log without this patch:
      
      	INFO: task kslowd004:5711 blocked for more than 120 seconds.
      	"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
      	kslowd004     D 0000000000000000     0  5711      2 0x00000080
      	 ffff88000340bb80 0000000000000046 ffff88002550d000 0000000000000000
      	 ffff88002550d000 0000000000000007 ffff88000340bfd8 ffff88002550d2a8
      	 000000000000ddf0 00000000000118c0 00000000000118c0 ffff88002550d2a8
      	Call Trace:
      	 [<ffffffff81058e21>] ? trace_hardirqs_on+0xd/0xf
      	 [<ffffffffa011c4d8>] ? cachefiles_wait_bit+0x0/0xd [cachefiles]
      	 [<ffffffffa011c4e1>] cachefiles_wait_bit+0x9/0xd [cachefiles]
      	 [<ffffffff81353153>] __wait_on_bit+0x43/0x76
      	 [<ffffffff8111ae39>] ? ext3_xattr_get+0x1ec/0x270
      	 [<ffffffff813531ef>] out_of_line_wait_on_bit+0x69/0x74
      	 [<ffffffffa011c4d8>] ? cachefiles_wait_bit+0x0/0xd [cachefiles]
      	 [<ffffffff8104c125>] ? wake_bit_function+0x0/0x2e
      	 [<ffffffffa011bc79>] cachefiles_mark_object_active+0x203/0x23b [cachefiles]
      	 [<ffffffffa011c209>] cachefiles_walk_to_object+0x558/0x827 [cachefiles]
      	 [<ffffffffa011a429>] cachefiles_lookup_object+0xac/0x12a [cachefiles]
      	 [<ffffffffa00aa1e9>] fscache_lookup_object+0x1c7/0x214 [fscache]
      	 [<ffffffffa00aafc5>] fscache_object_state_machine+0xa5/0x52d [fscache]
      	 [<ffffffffa00ab4ac>] fscache_object_slow_work_execute+0x5f/0xa0 [fscache]
      	 [<ffffffff81082093>] slow_work_execute+0x18f/0x2d1
      	 [<ffffffff8108239a>] slow_work_thread+0x1c5/0x308
      	 [<ffffffff8104c0f1>] ? autoremove_wake_function+0x0/0x34
      	 [<ffffffff810821d5>] ? slow_work_thread+0x0/0x308
      	 [<ffffffff8104be91>] kthread+0x7a/0x82
      	 [<ffffffff8100beda>] child_rip+0xa/0x20
      	 [<ffffffff8100b87c>] ? restore_args+0x0/0x30
      	 [<ffffffff8104be17>] ? kthread+0x0/0x82
      	 [<ffffffff8100bed0>] ? child_rip+0x0/0x20
      	1 lock held by kslowd004/5711:
      	 #0:  (&sb->s_type->i_mutex_key#7/1){+.+.+.}, at: [<ffffffffa011be64>] cachefiles_walk_to_object+0x1b3/0x827 [cachefiles]
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      fee096de
    • D
      FS-Cache: Actually requeue an object when requested · 868411be
      David Howells 提交于
      FS-Cache objects have an FSCACHE_OBJECT_EV_REQUEUE event that can theoretically
      be raised to ask the state machine to requeue the object for further processing
      before the work function returns to the slow-work facility.
      
      However, fscache_object_work_execute() was clearing that bit before checking
      the event mask to see whether the object has any pending events that require it
      to be requeued immediately.
      
      Instead, the bit should be cleared after the check and enqueue.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      868411be
    • D
      FS-Cache: Start processing an object's operations on that object's death · 60d543ca
      David Howells 提交于
      Start processing an object's operations when that object moves into the DYING
      state as the object cannot be destroyed until all its outstanding operations
      have completed.
      
      Furthermore, make sure that read and allocation operations handle being woken
      up on a dead object.  Such events are recorded in the Allocs.abt and
      Retrvls.abt statistics as viewable through /proc/fs/fscache/stats.
      
      The code for waiting for object activation for the read and allocation
      operations is also extracted into its own function as it is much the same in
      all cases, differing only in the stats incremented.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      60d543ca
    • D
      FS-Cache: Make sure FSCACHE_COOKIE_LOOKING_UP cleared on lookup failure · d461d26d
      David Howells 提交于
      We must make sure that FSCACHE_COOKIE_LOOKING_UP is cleared on lookup failure
      (if an object reaches the LC_DYING state), and we should clear it before
      clearing FSCACHE_COOKIE_CREATING.
      
      If this doesn't happen then fscache_wait_for_deferred_lookup() may hold
      allocation and retrieval operations indefinitely until they're interrupted by
      signals - which in turn pins the dying object until they go away.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      d461d26d
    • D
      FS-Cache: The object-available state can't rely on the cookie to be available · 6897e3df
      David Howells 提交于
      The object-available state in the object processing state machine (as
      processed by fscache_object_available()) can't rely on the cookie to be
      available because the FSCACHE_COOKIE_CREATING bit may have been cleared by
      fscache_obtained_object() prior to the object being put into the
      FSCACHE_OBJECT_AVAILABLE state.
      
      Clearing the FSCACHE_COOKIE_CREATING bit on a cookie permits
      __fscache_relinquish_cookie() to proceed and detach the cookie from the
      object.
      
      To deal with this, we don't dereference object->cookie in
      fscache_object_available() if the object has already been detached.
      
      In addition, a couple of assertions are added into fscache_drop_object() to
      make sure the object is unbound from the cookie before it gets there.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      6897e3df
    • D
      FS-Cache: Add counters for entry/exit to/from cache operation functions · 52bd75fd
      David Howells 提交于
      Count entries to and exits from cache operation table functions.  Maintain
      these as a single counter that's added to or removed from as appropriate.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      52bd75fd
    • D
      FS-Cache: Allow the current state of all objects to be dumped · 4fbf4291
      David Howells 提交于
      Allow the current state of all fscache objects to be dumped by doing:
      
      	cat /proc/fs/fscache/objects
      
      By default, all objects and all fields will be shown.  This can be restricted
      by adding a suitable key to one of the caller's keyrings (such as the session
      keyring):
      
      	keyctl add user fscache:objlist "<restrictions>" @s
      
      The <restrictions> are:
      
      	K	Show hexdump of object key (don't show if not given)
      	A	Show hexdump of object aux data (don't show if not given)
      
      And paired restrictions:
      
      	C	Show objects that have a cookie
      	c	Show objects that don't have a cookie
      	B	Show objects that are busy
      	b	Show objects that aren't busy
      	W	Show objects that have pending writes
      	w	Show objects that don't have pending writes
      	R	Show objects that have outstanding reads
      	r	Show objects that don't have outstanding reads
      	S	Show objects that have slow work queued
      	s	Show objects that don't have slow work queued
      
      If neither side of a restriction pair is given, then both are implied.  For
      example:
      
      	keyctl add user fscache:objlist KB @s
      
      shows objects that are busy, and lists their object keys, but does not dump
      their auxiliary data.  It also implies "CcWwRrSs", but as 'B' is given, 'b' is
      not implied.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      4fbf4291
    • D
      FS-Cache: Annotate slow-work runqueue proc lines for FS-Cache work items · 440f0aff
      David Howells 提交于
      Annotate slow-work runqueue proc lines for FS-Cache work items.  Objects
      include the object ID and the state.  Operations include the object ID, the
      operation ID and the operation type and state.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      440f0aff
    • D
      SLOW_WORK: Wait for outstanding work items belonging to a module to clear · 3d7a641e
      David Howells 提交于
      Wait for outstanding slow work items belonging to a module to clear when
      unregistering that module as a user of the facility.  This prevents the put_ref
      code of a work item from being taken away before it returns.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      3d7a641e
  4. 03 4月, 2009 1 次提交
    • D
      FS-Cache: Object management state machine · 36c95590
      David Howells 提交于
      Implement the cache object management state machine.
      
      The following documentation is added to illuminate the working of this state
      machine.  It will also be added as:
      
      	Documentation/filesystems/caching/object.txt
      
      	     ====================================================
      	     IN-KERNEL CACHE OBJECT REPRESENTATION AND MANAGEMENT
      	     ====================================================
      
      ==============
      REPRESENTATION
      ==============
      
      FS-Cache maintains an in-kernel representation of each object that a netfs is
      currently interested in.  Such objects are represented by the fscache_cookie
      struct and are referred to as cookies.
      
      FS-Cache also maintains a separate in-kernel representation of the objects that
      a cache backend is currently actively caching.  Such objects are represented by
      the fscache_object struct.  The cache backends allocate these upon request, and
      are expected to embed them in their own representations.  These are referred to
      as objects.
      
      There is a 1:N relationship between cookies and objects.  A cookie may be
      represented by multiple objects - an index may exist in more than one cache -
      or even by no objects (it may not be cached).
      
      Furthermore, both cookies and objects are hierarchical.  The two hierarchies
      correspond, but the cookies tree is a superset of the union of the object trees
      of multiple caches:
      
      	    NETFS INDEX TREE               :      CACHE 1     :      CACHE 2
      	                                   :                  :
      	                                   :   +-----------+  :
      	                          +----------->|  IObject  |  :
      	      +-----------+       |        :   +-----------+  :
      	      |  ICookie  |-------+        :         |        :
      	      +-----------+       |        :         |        :   +-----------+
      	            |             +------------------------------>|  IObject  |
      	            |                      :         |        :   +-----------+
      	            |                      :         V        :         |
      	            |                      :   +-----------+  :         |
      	            V             +----------->|  IObject  |  :         |
      	      +-----------+       |        :   +-----------+  :         |
      	      |  ICookie  |-------+        :         |        :         V
      	      +-----------+       |        :         |        :   +-----------+
      	            |             +------------------------------>|  IObject  |
      	      +-----+-----+                :         |        :   +-----------+
      	      |           |                :         |        :         |
      	      V           |                :         V        :         |
      	+-----------+     |                :   +-----------+  :         |
      	|  ICookie  |------------------------->|  IObject  |  :         |
      	+-----------+     |                :   +-----------+  :         |
      	      |           V                :         |        :         V
      	      |     +-----------+          :         |        :   +-----------+
      	      |     |  ICookie  |-------------------------------->|  IObject  |
      	      |     +-----------+          :         |        :   +-----------+
      	      V           |                :         V        :         |
      	+-----------+     |                :   +-----------+  :         |
      	|  DCookie  |------------------------->|  DObject  |  :         |
      	+-----------+     |                :   +-----------+  :         |
      	                  |                :                  :         |
      	          +-------+-------+        :                  :         |
      	          |               |        :                  :         |
      	          V               V        :                  :         V
      	    +-----------+   +-----------+  :                  :   +-----------+
      	    |  DCookie  |   |  DCookie  |------------------------>|  DObject  |
      	    +-----------+   +-----------+  :                  :   +-----------+
      	                                   :                  :
      
      In the above illustration, ICookie and IObject represent indices and DCookie
      and DObject represent data storage objects.  Indices may have representation in
      multiple caches, but currently, non-index objects may not.  Objects of any type
      may also be entirely unrepresented.
      
      As far as the netfs API goes, the netfs is only actually permitted to see
      pointers to the cookies.  The cookies themselves and any objects attached to
      those cookies are hidden from it.
      
      ===============================
      OBJECT MANAGEMENT STATE MACHINE
      ===============================
      
      Within FS-Cache, each active object is managed by its own individual state
      machine.  The state for an object is kept in the fscache_object struct, in
      object->state.  A cookie may point to a set of objects that are in different
      states.
      
      Each state has an action associated with it that is invoked when the machine
      wakes up in that state.  There are four logical sets of states:
      
       (1) Preparation: states that wait for the parent objects to become ready.  The
           representations are hierarchical, and it is expected that an object must
           be created or accessed with respect to its parent object.
      
       (2) Initialisation: states that perform lookups in the cache and validate
           what's found and that create on disk any missing metadata.
      
       (3) Normal running: states that allow netfs operations on objects to proceed
           and that update the state of objects.
      
       (4) Termination: states that detach objects from their netfs cookies, that
           delete objects from disk, that handle disk and system errors and that free
           up in-memory resources.
      
      In most cases, transitioning between states is in response to signalled events.
      When a state has finished processing, it will usually set the mask of events in
      which it is interested (object->event_mask) and relinquish the worker thread.
      Then when an event is raised (by calling fscache_raise_event()), if the event
      is not masked, the object will be queued for processing (by calling
      fscache_enqueue_object()).
      
      PROVISION OF CPU TIME
      ---------------------
      
      The work to be done by the various states is given CPU time by the threads of
      the slow work facility (see Documentation/slow-work.txt).  This is used in
      preference to the workqueue facility because:
      
       (1) Threads may be completely occupied for very long periods of time by a
           particular work item.  These state actions may be doing sequences of
           synchronous, journalled disk accesses (lookup, mkdir, create, setxattr,
           getxattr, truncate, unlink, rmdir, rename).
      
       (2) Threads may do little actual work, but may rather spend a lot of time
           sleeping on I/O.  This means that single-threaded and 1-per-CPU-threaded
           workqueues don't necessarily have the right numbers of threads.
      
      LOCKING SIMPLIFICATION
      ----------------------
      
      Because only one worker thread may be operating on any particular object's
      state machine at once, this simplifies the locking, particularly with respect
      to disconnecting the netfs's representation of a cache object (fscache_cookie)
      from the cache backend's representation (fscache_object) - which may be
      requested from either end.
      
      =================
      THE SET OF STATES
      =================
      
      The object state machine has a set of states that it can be in.  There are
      preparation states in which the object sets itself up and waits for its parent
      object to transit to a state that allows access to its children:
      
       (1) State FSCACHE_OBJECT_INIT.
      
           Initialise the object and wait for the parent object to become active.  In
           the cache, it is expected that it will not be possible to look an object
           up from the parent object, until that parent object itself has been looked
           up.
      
      There are initialisation states in which the object sets itself up and accesses
      disk for the object metadata:
      
       (2) State FSCACHE_OBJECT_LOOKING_UP.
      
           Look up the object on disk, using the parent as a starting point.
           FS-Cache expects the cache backend to probe the cache to see whether this
           object is represented there, and if it is, to see if it's valid (coherency
           management).
      
           The cache should call fscache_object_lookup_negative() to indicate lookup
           failure for whatever reason, and should call fscache_obtained_object() to
           indicate success.
      
           At the completion of lookup, FS-Cache will let the netfs go ahead with
           read operations, no matter whether the file is yet cached.  If not yet
           cached, read operations will be immediately rejected with ENODATA until
           the first known page is uncached - as to that point there can be no data
           to be read out of the cache for that file that isn't currently also held
           in the pagecache.
      
       (3) State FSCACHE_OBJECT_CREATING.
      
           Create an object on disk, using the parent as a starting point.  This
           happens if the lookup failed to find the object, or if the object's
           coherency data indicated what's on disk is out of date.  In this state,
           FS-Cache expects the cache to create
      
           The cache should call fscache_obtained_object() if creation completes
           successfully, fscache_object_lookup_negative() otherwise.
      
           At the completion of creation, FS-Cache will start processing write
           operations the netfs has queued for an object.  If creation failed, the
           write ops will be transparently discarded, and nothing recorded in the
           cache.
      
      There are some normal running states in which the object spends its time
      servicing netfs requests:
      
       (4) State FSCACHE_OBJECT_AVAILABLE.
      
           A transient state in which pending operations are started, child objects
           are permitted to advance from FSCACHE_OBJECT_INIT state, and temporary
           lookup data is freed.
      
       (5) State FSCACHE_OBJECT_ACTIVE.
      
           The normal running state.  In this state, requests the netfs makes will be
           passed on to the cache.
      
       (6) State FSCACHE_OBJECT_UPDATING.
      
           The state machine comes here to update the object in the cache from the
           netfs's records.  This involves updating the auxiliary data that is used
           to maintain coherency.
      
      And there are terminal states in which an object cleans itself up, deallocates
      memory and potentially deletes stuff from disk:
      
       (7) State FSCACHE_OBJECT_LC_DYING.
      
           The object comes here if it is dying because of a lookup or creation
           error.  This would be due to a disk error or system error of some sort.
           Temporary data is cleaned up, and the parent is released.
      
       (8) State FSCACHE_OBJECT_DYING.
      
           The object comes here if it is dying due to an error, because its parent
           cookie has been relinquished by the netfs or because the cache is being
           withdrawn.
      
           Any child objects waiting on this one are given CPU time so that they too
           can destroy themselves.  This object waits for all its children to go away
           before advancing to the next state.
      
       (9) State FSCACHE_OBJECT_ABORT_INIT.
      
           The object comes to this state if it was waiting on its parent in
           FSCACHE_OBJECT_INIT, but its parent died.  The object will destroy itself
           so that the parent may proceed from the FSCACHE_OBJECT_DYING state.
      
      (10) State FSCACHE_OBJECT_RELEASING.
      (11) State FSCACHE_OBJECT_RECYCLING.
      
           The object comes to one of these two states when dying once it is rid of
           all its children, if it is dying because the netfs relinquished its
           cookie.  In the first state, the cached data is expected to persist, and
           in the second it will be deleted.
      
      (12) State FSCACHE_OBJECT_WITHDRAWING.
      
           The object transits to this state if the cache decides it wants to
           withdraw the object from service, perhaps to make space, but also due to
           error or just because the whole cache is being withdrawn.
      
      (13) State FSCACHE_OBJECT_DEAD.
      
           The object transits to this state when the in-memory object record is
           ready to be deleted.  The object processor shouldn't ever see an object in
           this state.
      
      THE SET OF EVENTS
      -----------------
      
      There are a number of events that can be raised to an object state machine:
      
       (*) FSCACHE_OBJECT_EV_UPDATE
      
           The netfs requested that an object be updated.  The state machine will ask
           the cache backend to update the object, and the cache backend will ask the
           netfs for details of the change through its cookie definition ops.
      
       (*) FSCACHE_OBJECT_EV_CLEARED
      
           This is signalled in two circumstances:
      
           (a) when an object's last child object is dropped and
      
           (b) when the last operation outstanding on an object is completed.
      
           This is used to proceed from the dying state.
      
       (*) FSCACHE_OBJECT_EV_ERROR
      
           This is signalled when an I/O error occurs during the processing of some
           object.
      
       (*) FSCACHE_OBJECT_EV_RELEASE
       (*) FSCACHE_OBJECT_EV_RETIRE
      
           These are signalled when the netfs relinquishes a cookie it was using.
           The event selected depends on whether the netfs asks for the backing
           object to be retired (deleted) or retained.
      
       (*) FSCACHE_OBJECT_EV_WITHDRAW
      
           This is signalled when the cache backend wants to withdraw an object.
           This means that the object will have to be detached from the netfs's
           cookie.
      
      Because the withdrawing releasing/retiring events are all handled by the object
      state machine, it doesn't matter if there's a collision with both ends trying
      to sever the connection at the same time.  The state machine can just pick
      which one it wants to honour, and that effects the other.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NSteve Dickson <steved@redhat.com>
      Acked-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
      Acked-by: NAl Viro <viro@zeniv.linux.org.uk>
      Tested-by: NDaire Byrne <Daire.Byrne@framestore.com>
      36c95590