]> Git Repo - linux.git/commitdiff
Merge tag 'fscache-20130702' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowell...
authorLinus Torvalds <[email protected]>
Tue, 2 Jul 2013 16:52:47 +0000 (09:52 -0700)
committerLinus Torvalds <[email protected]>
Tue, 2 Jul 2013 16:52:47 +0000 (09:52 -0700)
Pull FS-Cache updates from David Howells:
 "This contains a number of fixes for various FS-Cache issues plus some
  cleanups.  The commits are, in order:

   1) Provide a system wait_on_atomic_t() and wake_up_atomic_t() sharing
      the bit-wait table (enhancement for #8).

   2) Don't put spin_lock() in a while-condition as spin_lock() may have
      a do {} while(0) wrapper (cleanup).

   3) Symbolically name i_mutex lock classes rather than using numbers
      in CacheFiles (cleanup).

   4) Don't sleep in page release if __GFP_FS is not set (deadlock vs
      ext4).

   5) Uninline fscache_object_init() (cleanup for #7).

   6) Wrap checks on object state (cleanup for #7).

   7) Simplify the object state machine by separating work states from
      wait states.

   8) Simplify cookie retention by objects (NULL pointer deref fix).

   9) Remove unused list_to_page() macro (cleanup).

  10) Make the remaining-pages counter in the retrieval op atomic
      (assertion failure fix).

  11) Don't use spin_is_locked() in assertions (assertion failure fix)"

* tag 'fscache-20130702' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
  FS-Cache: Don't use spin_is_locked() in assertions
  FS-Cache: The retrieval remaining-pages counter needs to be atomic_t
  cachefiles: remove unused macro list_to_page()
  FS-Cache: Simplify cookie retention for fscache_objects, fixing oops
  FS-Cache: Fix object state machine to have separate work and wait states
  FS-Cache: Wrap checks on object state
  FS-Cache: Uninline fscache_object_init()
  FS-Cache: Don't sleep in page release if __GFP_FS is not set
  CacheFiles: name i_mutex lock class explicitly
  fs/fscache: remove spin_lock() from the condition in while()
  Add wait_on_atomic_t() and wake_up_atomic_t()

1  2 
include/linux/wait.h

diff --combined include/linux/wait.h
index 1133695eb0671d7aeb7f9140bf2b6adc3bc7483d,5bacfc4b336d2af5ef4e72e15ff6b93ec14a0385..f487a4750b7f36e97acef1542cb6076d76ce7a59
@@@ -23,6 -23,7 +23,7 @@@ struct __wait_queue 
  struct wait_bit_key {
        void *flags;
        int bit_nr;
+ #define WAIT_ATOMIC_T_BIT_NR -1
  };
  
  struct wait_bit_queue {
@@@ -60,6 -61,9 +61,9 @@@ struct task_struct
  #define __WAIT_BIT_KEY_INITIALIZER(word, bit)                         \
        { .flags = word, .bit_nr = bit, }
  
+ #define __WAIT_ATOMIC_T_KEY_INITIALIZER(p)                            \
+       { .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, }
  extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *);
  
  #define init_waitqueue_head(q)                                \
@@@ -146,8 -150,10 +150,10 @@@ void __wake_up_bit(wait_queue_head_t *
  int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned);
  int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned);
  void wake_up_bit(void *, int);
+ void wake_up_atomic_t(atomic_t *);
  int out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned);
  int out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned);
+ int out_of_line_wait_on_atomic_t(atomic_t *, int (*)(atomic_t *), unsigned);
  wait_queue_head_t *bit_waitqueue(void *, int);
  
  #define wake_up(x)                    __wake_up(x, TASK_NORMAL, 1, NULL)
@@@ -217,8 -223,6 +223,8 @@@ do {                                                                       
                if (!ret)                                               \
                        break;                                          \
        }                                                               \
 +      if (!ret && (condition))                                        \
 +              ret = 1;                                                \
        finish_wait(&wq, &__wait);                                      \
  } while (0)
  
   * wake_up() has to be called after changing any variable that could
   * change the result of the wait condition.
   *
 - * The function returns 0 if the @timeout elapsed, and the remaining
 - * jiffies if the condition evaluated to true before the timeout elapsed.
 + * The function returns 0 if the @timeout elapsed, or the remaining
 + * jiffies (at least 1) if the @condition evaluated to %true before
 + * the @timeout elapsed.
   */
  #define wait_event_timeout(wq, condition, timeout)                    \
  ({                                                                    \
@@@ -305,8 -308,6 +311,8 @@@ do {                                                                       
                ret = -ERESTARTSYS;                                     \
                break;                                                  \
        }                                                               \
 +      if (!ret && (condition))                                        \
 +              ret = 1;                                                \
        finish_wait(&wq, &__wait);                                      \
  } while (0)
  
   * wake_up() has to be called after changing any variable that could
   * change the result of the wait condition.
   *
 - * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it
 - * was interrupted by a signal, and the remaining jiffies otherwise
 - * if the condition evaluated to true before the timeout elapsed.
 + * Returns:
 + * 0 if the @timeout elapsed, -%ERESTARTSYS if it was interrupted by
 + * a signal, or the remaining jiffies (at least 1) if the @condition
 + * evaluated to %true before the @timeout elapsed.
   */
  #define wait_event_interruptible_timeout(wq, condition, timeout)      \
  ({                                                                    \
@@@ -902,5 -902,23 +908,23 @@@ static inline int wait_on_bit_lock(voi
                return 0;
        return out_of_line_wait_on_bit_lock(word, bit, action, mode);
  }
+ /**
+  * wait_on_atomic_t - Wait for an atomic_t to become 0
+  * @val: The atomic value being waited on, a kernel virtual address
+  * @action: the function used to sleep, which may take special actions
+  * @mode: the task state to sleep in
+  *
+  * Wait for an atomic_t to become 0.  We abuse the bit-wait waitqueue table for
+  * the purpose of getting a waitqueue, but we set the key to a bit number
+  * outside of the target 'word'.
+  */
+ static inline
+ int wait_on_atomic_t(atomic_t *val, int (*action)(atomic_t *), unsigned mode)
+ {
+       if (atomic_read(val) == 0)
+               return 0;
+       return out_of_line_wait_on_atomic_t(val, action, mode);
+ }
        
  #endif
This page took 0.061033 seconds and 4 git commands to generate.