1  /* SPDX-License-Identifier: GPL-2.0 */
2  #ifndef __LINUX_SPINLOCK_H
3  #define __LINUX_SPINLOCK_H
4  #define __LINUX_INSIDE_SPINLOCK_H
5  
6  /*
7   * include/linux/spinlock.h - generic spinlock/rwlock declarations
8   *
9   * here's the role of the various spinlock/rwlock related include files:
10   *
11   * on SMP builds:
12   *
13   *  asm/spinlock_types.h: contains the arch_spinlock_t/arch_rwlock_t and the
14   *                        initializers
15   *
16   *  linux/spinlock_types_raw:
17   *			  The raw types and initializers
18   *  linux/spinlock_types.h:
19   *                        defines the generic type and initializers
20   *
21   *  asm/spinlock.h:       contains the arch_spin_*()/etc. lowlevel
22   *                        implementations, mostly inline assembly code
23   *
24   *   (also included on UP-debug builds:)
25   *
26   *  linux/spinlock_api_smp.h:
27   *                        contains the prototypes for the _spin_*() APIs.
28   *
29   *  linux/spinlock.h:     builds the final spin_*() APIs.
30   *
31   * on UP builds:
32   *
33   *  linux/spinlock_type_up.h:
34   *                        contains the generic, simplified UP spinlock type.
35   *                        (which is an empty structure on non-debug builds)
36   *
37   *  linux/spinlock_types_raw:
38   *			  The raw RT types and initializers
39   *  linux/spinlock_types.h:
40   *                        defines the generic type and initializers
41   *
42   *  linux/spinlock_up.h:
43   *                        contains the arch_spin_*()/etc. version of UP
44   *                        builds. (which are NOPs on non-debug, non-preempt
45   *                        builds)
46   *
47   *   (included on UP-non-debug builds:)
48   *
49   *  linux/spinlock_api_up.h:
50   *                        builds the _spin_*() APIs.
51   *
52   *  linux/spinlock.h:     builds the final spin_*() APIs.
53   */
54  
55  #include <linux/typecheck.h>
56  #include <linux/preempt.h>
57  #include <linux/linkage.h>
58  #include <linux/compiler.h>
59  #include <linux/irqflags.h>
60  #include <linux/thread_info.h>
61  #include <linux/stringify.h>
62  #include <linux/bottom_half.h>
63  #include <linux/lockdep.h>
64  #include <linux/cleanup.h>
65  #include <asm/barrier.h>
66  #include <asm/mmiowb.h>
67  
68  
69  /*
70   * Must define these before including other files, inline functions need them
71   */
72  #define LOCK_SECTION_NAME ".text..lock."KBUILD_BASENAME
73  
74  #define LOCK_SECTION_START(extra)               \
75          ".subsection 1\n\t"                     \
76          extra                                   \
77          ".ifndef " LOCK_SECTION_NAME "\n\t"     \
78          LOCK_SECTION_NAME ":\n\t"               \
79          ".endif\n"
80  
81  #define LOCK_SECTION_END                        \
82          ".previous\n\t"
83  
84  #define __lockfunc __section(".spinlock.text")
85  
86  /*
87   * Pull the arch_spinlock_t and arch_rwlock_t definitions:
88   */
89  #include <linux/spinlock_types.h>
90  
91  /*
92   * Pull the arch_spin*() functions/declarations (UP-nondebug doesn't need them):
93   */
94  #ifdef CONFIG_SMP
95  # include <asm/spinlock.h>
96  #else
97  # include <linux/spinlock_up.h>
98  #endif
99  
100  #ifdef CONFIG_DEBUG_SPINLOCK
101    extern void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
102  				   struct lock_class_key *key, short inner);
103  
104  # define raw_spin_lock_init(lock)					\
105  do {									\
106  	static struct lock_class_key __key;				\
107  									\
108  	__raw_spin_lock_init((lock), #lock, &__key, LD_WAIT_SPIN);	\
109  } while (0)
110  
111  #else
112  # define raw_spin_lock_init(lock)				\
113  	do { *(lock) = __RAW_SPIN_LOCK_UNLOCKED(lock); } while (0)
114  #endif
115  
116  #define raw_spin_is_locked(lock)	arch_spin_is_locked(&(lock)->raw_lock)
117  
118  #ifdef arch_spin_is_contended
119  #define raw_spin_is_contended(lock)	arch_spin_is_contended(&(lock)->raw_lock)
120  #else
121  #define raw_spin_is_contended(lock)	(((void)(lock), 0))
122  #endif /*arch_spin_is_contended*/
123  
124  /*
125   * smp_mb__after_spinlock() provides the equivalent of a full memory barrier
126   * between program-order earlier lock acquisitions and program-order later
127   * memory accesses.
128   *
129   * This guarantees that the following two properties hold:
130   *
131   *   1) Given the snippet:
132   *
133   *	  { X = 0;  Y = 0; }
134   *
135   *	  CPU0				CPU1
136   *
137   *	  WRITE_ONCE(X, 1);		WRITE_ONCE(Y, 1);
138   *	  spin_lock(S);			smp_mb();
139   *	  smp_mb__after_spinlock();	r1 = READ_ONCE(X);
140   *	  r0 = READ_ONCE(Y);
141   *	  spin_unlock(S);
142   *
143   *      it is forbidden that CPU0 does not observe CPU1's store to Y (r0 = 0)
144   *      and CPU1 does not observe CPU0's store to X (r1 = 0); see the comments
145   *      preceding the call to smp_mb__after_spinlock() in __schedule() and in
146   *      try_to_wake_up().
147   *
148   *   2) Given the snippet:
149   *
150   *  { X = 0;  Y = 0; }
151   *
152   *  CPU0		CPU1				CPU2
153   *
154   *  spin_lock(S);	spin_lock(S);			r1 = READ_ONCE(Y);
155   *  WRITE_ONCE(X, 1);	smp_mb__after_spinlock();	smp_rmb();
156   *  spin_unlock(S);	r0 = READ_ONCE(X);		r2 = READ_ONCE(X);
157   *			WRITE_ONCE(Y, 1);
158   *			spin_unlock(S);
159   *
160   *      it is forbidden that CPU0's critical section executes before CPU1's
161   *      critical section (r0 = 1), CPU2 observes CPU1's store to Y (r1 = 1)
162   *      and CPU2 does not observe CPU0's store to X (r2 = 0); see the comments
163   *      preceding the calls to smp_rmb() in try_to_wake_up() for similar
164   *      snippets but "projected" onto two CPUs.
165   *
166   * Property (2) upgrades the lock to an RCsc lock.
167   *
168   * Since most load-store architectures implement ACQUIRE with an smp_mb() after
169   * the LL/SC loop, they need no further barriers. Similarly all our TSO
170   * architectures imply an smp_mb() for each atomic instruction and equally don't
171   * need more.
172   *
173   * Architectures that can implement ACQUIRE better need to take care.
174   */
175  #ifndef smp_mb__after_spinlock
176  #define smp_mb__after_spinlock()	kcsan_mb()
177  #endif
178  
179  #ifdef CONFIG_DEBUG_SPINLOCK
180   extern void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock);
181   extern int do_raw_spin_trylock(raw_spinlock_t *lock);
182   extern void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock);
183  #else
do_raw_spin_lock(raw_spinlock_t * lock)184  static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
185  {
186  	__acquire(lock);
187  	arch_spin_lock(&lock->raw_lock);
188  	mmiowb_spin_lock();
189  }
190  
do_raw_spin_trylock(raw_spinlock_t * lock)191  static inline int do_raw_spin_trylock(raw_spinlock_t *lock)
192  {
193  	int ret = arch_spin_trylock(&(lock)->raw_lock);
194  
195  	if (ret)
196  		mmiowb_spin_lock();
197  
198  	return ret;
199  }
200  
do_raw_spin_unlock(raw_spinlock_t * lock)201  static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)
202  {
203  	mmiowb_spin_unlock();
204  	arch_spin_unlock(&lock->raw_lock);
205  	__release(lock);
206  }
207  #endif
208  
209  /*
210   * Define the various spin_lock methods.  Note we define these
211   * regardless of whether CONFIG_SMP or CONFIG_PREEMPTION are set. The
212   * various methods are defined as nops in the case they are not
213   * required.
214   */
215  #define raw_spin_trylock(lock)	__cond_lock(lock, _raw_spin_trylock(lock))
216  
217  #define raw_spin_lock(lock)	_raw_spin_lock(lock)
218  
219  #ifdef CONFIG_DEBUG_LOCK_ALLOC
220  # define raw_spin_lock_nested(lock, subclass) \
221  	_raw_spin_lock_nested(lock, subclass)
222  
223  # define raw_spin_lock_nest_lock(lock, nest_lock)			\
224  	 do {								\
225  		 typecheck(struct lockdep_map *, &(nest_lock)->dep_map);\
226  		 _raw_spin_lock_nest_lock(lock, &(nest_lock)->dep_map);	\
227  	 } while (0)
228  #else
229  /*
230   * Always evaluate the 'subclass' argument to avoid that the compiler
231   * warns about set-but-not-used variables when building with
232   * CONFIG_DEBUG_LOCK_ALLOC=n and with W=1.
233   */
234  # define raw_spin_lock_nested(lock, subclass)		\
235  	_raw_spin_lock(((void)(subclass), (lock)))
236  # define raw_spin_lock_nest_lock(lock, nest_lock)	_raw_spin_lock(lock)
237  #endif
238  
239  #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
240  
241  #define raw_spin_lock_irqsave(lock, flags)			\
242  	do {						\
243  		typecheck(unsigned long, flags);	\
244  		flags = _raw_spin_lock_irqsave(lock);	\
245  	} while (0)
246  
247  #ifdef CONFIG_DEBUG_LOCK_ALLOC
248  #define raw_spin_lock_irqsave_nested(lock, flags, subclass)		\
249  	do {								\
250  		typecheck(unsigned long, flags);			\
251  		flags = _raw_spin_lock_irqsave_nested(lock, subclass);	\
252  	} while (0)
253  #else
254  #define raw_spin_lock_irqsave_nested(lock, flags, subclass)		\
255  	do {								\
256  		typecheck(unsigned long, flags);			\
257  		flags = _raw_spin_lock_irqsave(lock);			\
258  	} while (0)
259  #endif
260  
261  #else
262  
263  #define raw_spin_lock_irqsave(lock, flags)		\
264  	do {						\
265  		typecheck(unsigned long, flags);	\
266  		_raw_spin_lock_irqsave(lock, flags);	\
267  	} while (0)
268  
269  #define raw_spin_lock_irqsave_nested(lock, flags, subclass)	\
270  	raw_spin_lock_irqsave(lock, flags)
271  
272  #endif
273  
274  #define raw_spin_lock_irq(lock)		_raw_spin_lock_irq(lock)
275  #define raw_spin_lock_bh(lock)		_raw_spin_lock_bh(lock)
276  #define raw_spin_unlock(lock)		_raw_spin_unlock(lock)
277  #define raw_spin_unlock_irq(lock)	_raw_spin_unlock_irq(lock)
278  
279  #define raw_spin_unlock_irqrestore(lock, flags)		\
280  	do {							\
281  		typecheck(unsigned long, flags);		\
282  		_raw_spin_unlock_irqrestore(lock, flags);	\
283  	} while (0)
284  #define raw_spin_unlock_bh(lock)	_raw_spin_unlock_bh(lock)
285  
286  #define raw_spin_trylock_bh(lock) \
287  	__cond_lock(lock, _raw_spin_trylock_bh(lock))
288  
289  #define raw_spin_trylock_irq(lock) \
290  ({ \
291  	local_irq_disable(); \
292  	raw_spin_trylock(lock) ? \
293  	1 : ({ local_irq_enable(); 0;  }); \
294  })
295  
296  #define raw_spin_trylock_irqsave(lock, flags) \
297  ({ \
298  	local_irq_save(flags); \
299  	raw_spin_trylock(lock) ? \
300  	1 : ({ local_irq_restore(flags); 0; }); \
301  })
302  
303  #ifndef CONFIG_PREEMPT_RT
304  /* Include rwlock functions for !RT */
305  #include <linux/rwlock.h>
306  #endif
307  
308  /*
309   * Pull the _spin_*()/_read_*()/_write_*() functions/declarations:
310   */
311  #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
312  # include <linux/spinlock_api_smp.h>
313  #else
314  # include <linux/spinlock_api_up.h>
315  #endif
316  
317  /* Non PREEMPT_RT kernel, map to raw spinlocks: */
318  #ifndef CONFIG_PREEMPT_RT
319  
320  /*
321   * Map the spin_lock functions to the raw variants for PREEMPT_RT=n
322   */
323  
spinlock_check(spinlock_t * lock)324  static __always_inline raw_spinlock_t *spinlock_check(spinlock_t *lock)
325  {
326  	return &lock->rlock;
327  }
328  
329  #ifdef CONFIG_DEBUG_SPINLOCK
330  
331  # define spin_lock_init(lock)					\
332  do {								\
333  	static struct lock_class_key __key;			\
334  								\
335  	__raw_spin_lock_init(spinlock_check(lock),		\
336  			     #lock, &__key, LD_WAIT_CONFIG);	\
337  } while (0)
338  
339  #else
340  
341  # define spin_lock_init(_lock)			\
342  do {						\
343  	spinlock_check(_lock);			\
344  	*(_lock) = __SPIN_LOCK_UNLOCKED(_lock);	\
345  } while (0)
346  
347  #endif
348  
spin_lock(spinlock_t * lock)349  static __always_inline void spin_lock(spinlock_t *lock)
350  {
351  	raw_spin_lock(&lock->rlock);
352  }
353  
spin_lock_bh(spinlock_t * lock)354  static __always_inline void spin_lock_bh(spinlock_t *lock)
355  {
356  	raw_spin_lock_bh(&lock->rlock);
357  }
358  
spin_trylock(spinlock_t * lock)359  static __always_inline int spin_trylock(spinlock_t *lock)
360  {
361  	return raw_spin_trylock(&lock->rlock);
362  }
363  
364  #define spin_lock_nested(lock, subclass)			\
365  do {								\
366  	raw_spin_lock_nested(spinlock_check(lock), subclass);	\
367  } while (0)
368  
369  #define spin_lock_nest_lock(lock, nest_lock)				\
370  do {									\
371  	raw_spin_lock_nest_lock(spinlock_check(lock), nest_lock);	\
372  } while (0)
373  
spin_lock_irq(spinlock_t * lock)374  static __always_inline void spin_lock_irq(spinlock_t *lock)
375  {
376  	raw_spin_lock_irq(&lock->rlock);
377  }
378  
379  #define spin_lock_irqsave(lock, flags)				\
380  do {								\
381  	raw_spin_lock_irqsave(spinlock_check(lock), flags);	\
382  } while (0)
383  
384  #define spin_lock_irqsave_nested(lock, flags, subclass)			\
385  do {									\
386  	raw_spin_lock_irqsave_nested(spinlock_check(lock), flags, subclass); \
387  } while (0)
388  
spin_unlock(spinlock_t * lock)389  static __always_inline void spin_unlock(spinlock_t *lock)
390  {
391  	raw_spin_unlock(&lock->rlock);
392  }
393  
spin_unlock_bh(spinlock_t * lock)394  static __always_inline void spin_unlock_bh(spinlock_t *lock)
395  {
396  	raw_spin_unlock_bh(&lock->rlock);
397  }
398  
spin_unlock_irq(spinlock_t * lock)399  static __always_inline void spin_unlock_irq(spinlock_t *lock)
400  {
401  	raw_spin_unlock_irq(&lock->rlock);
402  }
403  
spin_unlock_irqrestore(spinlock_t * lock,unsigned long flags)404  static __always_inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
405  {
406  	raw_spin_unlock_irqrestore(&lock->rlock, flags);
407  }
408  
spin_trylock_bh(spinlock_t * lock)409  static __always_inline int spin_trylock_bh(spinlock_t *lock)
410  {
411  	return raw_spin_trylock_bh(&lock->rlock);
412  }
413  
spin_trylock_irq(spinlock_t * lock)414  static __always_inline int spin_trylock_irq(spinlock_t *lock)
415  {
416  	return raw_spin_trylock_irq(&lock->rlock);
417  }
418  
419  #define spin_trylock_irqsave(lock, flags)			\
420  ({								\
421  	raw_spin_trylock_irqsave(spinlock_check(lock), flags); \
422  })
423  
424  /**
425   * spin_is_locked() - Check whether a spinlock is locked.
426   * @lock: Pointer to the spinlock.
427   *
428   * This function is NOT required to provide any memory ordering
429   * guarantees; it could be used for debugging purposes or, when
430   * additional synchronization is needed, accompanied with other
431   * constructs (memory barriers) enforcing the synchronization.
432   *
433   * Returns: 1 if @lock is locked, 0 otherwise.
434   *
435   * Note that the function only tells you that the spinlock is
436   * seen to be locked, not that it is locked on your CPU.
437   *
438   * Further, on CONFIG_SMP=n builds with CONFIG_DEBUG_SPINLOCK=n,
439   * the return value is always 0 (see include/linux/spinlock_up.h).
440   * Therefore you should not rely heavily on the return value.
441   */
spin_is_locked(spinlock_t * lock)442  static __always_inline int spin_is_locked(spinlock_t *lock)
443  {
444  	return raw_spin_is_locked(&lock->rlock);
445  }
446  
spin_is_contended(spinlock_t * lock)447  static __always_inline int spin_is_contended(spinlock_t *lock)
448  {
449  	return raw_spin_is_contended(&lock->rlock);
450  }
451  
452  #define assert_spin_locked(lock)	assert_raw_spin_locked(&(lock)->rlock)
453  
454  #else  /* !CONFIG_PREEMPT_RT */
455  # include <linux/spinlock_rt.h>
456  #endif /* CONFIG_PREEMPT_RT */
457  
458  /*
459   * Does a critical section need to be broken due to another
460   * task waiting?: (technically does not depend on CONFIG_PREEMPTION,
461   * but a general need for low latency)
462   */
spin_needbreak(spinlock_t * lock)463  static inline int spin_needbreak(spinlock_t *lock)
464  {
465  	if (!preempt_model_preemptible())
466  		return 0;
467  
468  	return spin_is_contended(lock);
469  }
470  
471  /*
472   * Check if a rwlock is contended.
473   * Returns non-zero if there is another task waiting on the rwlock.
474   * Returns zero if the lock is not contended or the system / underlying
475   * rwlock implementation does not support contention detection.
476   * Technically does not depend on CONFIG_PREEMPTION, but a general need
477   * for low latency.
478   */
rwlock_needbreak(rwlock_t * lock)479  static inline int rwlock_needbreak(rwlock_t *lock)
480  {
481  	if (!preempt_model_preemptible())
482  		return 0;
483  
484  	return rwlock_is_contended(lock);
485  }
486  
487  /*
488   * Pull the atomic_t declaration:
489   * (asm-mips/atomic.h needs above definitions)
490   */
491  #include <linux/atomic.h>
492  /**
493   * atomic_dec_and_lock - lock on reaching reference count zero
494   * @atomic: the atomic counter
495   * @lock: the spinlock in question
496   *
497   * Decrements @atomic by 1.  If the result is 0, returns true and locks
498   * @lock.  Returns false for all other cases.
499   */
500  extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
501  #define atomic_dec_and_lock(atomic, lock) \
502  		__cond_lock(lock, _atomic_dec_and_lock(atomic, lock))
503  
504  extern int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock,
505  					unsigned long *flags);
506  #define atomic_dec_and_lock_irqsave(atomic, lock, flags) \
507  		__cond_lock(lock, _atomic_dec_and_lock_irqsave(atomic, lock, &(flags)))
508  
509  extern int _atomic_dec_and_raw_lock(atomic_t *atomic, raw_spinlock_t *lock);
510  #define atomic_dec_and_raw_lock(atomic, lock) \
511  		__cond_lock(lock, _atomic_dec_and_raw_lock(atomic, lock))
512  
513  extern int _atomic_dec_and_raw_lock_irqsave(atomic_t *atomic, raw_spinlock_t *lock,
514  					unsigned long *flags);
515  #define atomic_dec_and_raw_lock_irqsave(atomic, lock, flags) \
516  		__cond_lock(lock, _atomic_dec_and_raw_lock_irqsave(atomic, lock, &(flags)))
517  
518  int __alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask,
519  			     size_t max_size, unsigned int cpu_mult,
520  			     gfp_t gfp, const char *name,
521  			     struct lock_class_key *key);
522  
523  #define alloc_bucket_spinlocks(locks, lock_mask, max_size, cpu_mult, gfp)    \
524  	({								     \
525  		static struct lock_class_key key;			     \
526  		int ret;						     \
527  									     \
528  		ret = __alloc_bucket_spinlocks(locks, lock_mask, max_size,   \
529  					       cpu_mult, gfp, #locks, &key); \
530  		ret;							     \
531  	})
532  
533  void free_bucket_spinlocks(spinlock_t *locks);
534  
535  DEFINE_LOCK_GUARD_1(raw_spinlock, raw_spinlock_t,
536  		    raw_spin_lock(_T->lock),
537  		    raw_spin_unlock(_T->lock))
538  
539  DEFINE_LOCK_GUARD_1_COND(raw_spinlock, _try, raw_spin_trylock(_T->lock))
540  
541  DEFINE_LOCK_GUARD_1(raw_spinlock_nested, raw_spinlock_t,
542  		    raw_spin_lock_nested(_T->lock, SINGLE_DEPTH_NESTING),
543  		    raw_spin_unlock(_T->lock))
544  
545  DEFINE_LOCK_GUARD_1(raw_spinlock_irq, raw_spinlock_t,
546  		    raw_spin_lock_irq(_T->lock),
547  		    raw_spin_unlock_irq(_T->lock))
548  
549  DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irq, _try, raw_spin_trylock_irq(_T->lock))
550  
551  DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
552  		    raw_spin_lock_irqsave(_T->lock, _T->flags),
553  		    raw_spin_unlock_irqrestore(_T->lock, _T->flags),
554  		    unsigned long flags)
555  
556  DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try,
557  			 raw_spin_trylock_irqsave(_T->lock, _T->flags))
558  
559  DEFINE_LOCK_GUARD_1(spinlock, spinlock_t,
560  		    spin_lock(_T->lock),
561  		    spin_unlock(_T->lock))
562  
563  DEFINE_LOCK_GUARD_1_COND(spinlock, _try, spin_trylock(_T->lock))
564  
565  DEFINE_LOCK_GUARD_1(spinlock_irq, spinlock_t,
566  		    spin_lock_irq(_T->lock),
567  		    spin_unlock_irq(_T->lock))
568  
569  DEFINE_LOCK_GUARD_1_COND(spinlock_irq, _try,
570  			 spin_trylock_irq(_T->lock))
571  
572  DEFINE_LOCK_GUARD_1(spinlock_irqsave, spinlock_t,
573  		    spin_lock_irqsave(_T->lock, _T->flags),
574  		    spin_unlock_irqrestore(_T->lock, _T->flags),
575  		    unsigned long flags)
576  
577  DEFINE_LOCK_GUARD_1_COND(spinlock_irqsave, _try,
578  			 spin_trylock_irqsave(_T->lock, _T->flags))
579  
580  DEFINE_LOCK_GUARD_1(read_lock, rwlock_t,
581  		    read_lock(_T->lock),
582  		    read_unlock(_T->lock))
583  
584  DEFINE_LOCK_GUARD_1(read_lock_irq, rwlock_t,
585  		    read_lock_irq(_T->lock),
586  		    read_unlock_irq(_T->lock))
587  
588  DEFINE_LOCK_GUARD_1(read_lock_irqsave, rwlock_t,
589  		    read_lock_irqsave(_T->lock, _T->flags),
590  		    read_unlock_irqrestore(_T->lock, _T->flags),
591  		    unsigned long flags)
592  
593  DEFINE_LOCK_GUARD_1(write_lock, rwlock_t,
594  		    write_lock(_T->lock),
595  		    write_unlock(_T->lock))
596  
597  DEFINE_LOCK_GUARD_1(write_lock_irq, rwlock_t,
598  		    write_lock_irq(_T->lock),
599  		    write_unlock_irq(_T->lock))
600  
601  DEFINE_LOCK_GUARD_1(write_lock_irqsave, rwlock_t,
602  		    write_lock_irqsave(_T->lock, _T->flags),
603  		    write_unlock_irqrestore(_T->lock, _T->flags),
604  		    unsigned long flags)
605  
606  #undef __LINUX_INSIDE_SPINLOCK_H
607  #endif /* __LINUX_SPINLOCK_H */
608