Blame view

include/linux/percpu_counter.h 4.26 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  /* SPDX-License-Identifier: GPL-2.0 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
  #ifndef _LINUX_PERCPU_COUNTER_H
  #define _LINUX_PERCPU_COUNTER_H
  /*
   * A simple "approximate counter" for use in ext2 and ext3 superblocks.
   *
   * WARNING: these things are HUGE.  4 kbytes per counter on 32-way P4.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
  #include <linux/spinlock.h>
  #include <linux/smp.h>
c67ad917c   Andrew Morton   percpu_counters()...
11
  #include <linux/list.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
  #include <linux/threads.h>
  #include <linux/percpu.h>
0216bfcff   Mingming Cao   [PATCH] percpu co...
14
  #include <linux/types.h>
908c7f194   Tejun Heo   percpu_counter: a...
15
  #include <linux/gfp.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
19
  
  #ifdef CONFIG_SMP
  
  struct percpu_counter {
f032a4508   Thomas Gleixner   locking, percpu_c...
20
  	raw_spinlock_t lock;
0216bfcff   Mingming Cao   [PATCH] percpu co...
21
  	s64 count;
c67ad917c   Andrew Morton   percpu_counters()...
22
23
24
  #ifdef CONFIG_HOTPLUG_CPU
  	struct list_head list;	/* All percpu_counters are on a list */
  #endif
43cf38eb5   Tejun Heo   percpu: add __per...
25
  	s32 __percpu *counters;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  };
179f7ebff   Eric Dumazet   percpu_counter: F...
27
  extern int percpu_counter_batch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

908c7f194   Tejun Heo   percpu_counter: a...
29
  int __percpu_counter_init(struct percpu_counter *fbc, s64 amount, gfp_t gfp,
ea319518b   Peter Zijlstra   locking, percpu c...
30
  			  struct lock_class_key *key);
908c7f194   Tejun Heo   percpu_counter: a...
31
  #define percpu_counter_init(fbc, value, gfp)				\
ea319518b   Peter Zijlstra   locking, percpu c...
32
33
34
  	({								\
  		static struct lock_class_key __key;			\
  									\
908c7f194   Tejun Heo   percpu_counter: a...
35
  		__percpu_counter_init(fbc, value, gfp, &__key);		\
ea319518b   Peter Zijlstra   locking, percpu c...
36
  	})
c67ad917c   Andrew Morton   percpu_counters()...
37
  void percpu_counter_destroy(struct percpu_counter *fbc);
3a587f47b   Peter Zijlstra   lib: percpu_count...
38
  void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
104b4e513   Nikolay Borisov   percpu_counter: R...
39
40
  void percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount,
  			      s32 batch);
02d211688   Andrew Morton   revert "percpu_co...
41
  s64 __percpu_counter_sum(struct percpu_counter *fbc);
80188b0d7   Dave Chinner   percpu_counter: b...
42
43
44
45
46
47
  int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch);
  
  static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs)
  {
  	return __percpu_counter_compare(fbc, rhs, percpu_counter_batch);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48

20e897670   Peter Zijlstra   lib: make percpu_...
49
  static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount)
252e0ba6b   Peter Zijlstra   lib: percpu_count...
50
  {
104b4e513   Nikolay Borisov   percpu_counter: R...
51
  	percpu_counter_add_batch(fbc, amount, percpu_counter_batch);
252e0ba6b   Peter Zijlstra   lib: percpu_count...
52
  }
bf1d89c81   Peter Zijlstra   lib: percpu_count...
53
54
  static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
  {
02d211688   Andrew Morton   revert "percpu_co...
55
  	s64 ret = __percpu_counter_sum(fbc);
bf1d89c81   Peter Zijlstra   lib: percpu_count...
56
57
58
59
60
  	return ret < 0 ? 0 : ret;
  }
  
  static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
  {
02d211688   Andrew Morton   revert "percpu_co...
61
  	return __percpu_counter_sum(fbc);
bf1d89c81   Peter Zijlstra   lib: percpu_count...
62
  }
0216bfcff   Mingming Cao   [PATCH] percpu co...
63
  static inline s64 percpu_counter_read(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
66
67
68
69
70
  {
  	return fbc->count;
  }
  
  /*
   * It is possible for the percpu_counter_read() to return a small negative
   * number for some counter which should never be negative.
0216bfcff   Mingming Cao   [PATCH] percpu co...
71
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
   */
0216bfcff   Mingming Cao   [PATCH] percpu co...
73
  static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  {
0216bfcff   Mingming Cao   [PATCH] percpu co...
75
  	s64 ret = fbc->count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
  
  	barrier();		/* Prevent reloads of fbc->count */
0216bfcff   Mingming Cao   [PATCH] percpu co...
78
  	if (ret >= 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  		return ret;
c84598bbf   Shaohua Li   percpu_counter: c...
80
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  }
7f93cff90   Theodore Ts'o   ext4: fix kernel ...
82
83
84
85
  static inline int percpu_counter_initialized(struct percpu_counter *fbc)
  {
  	return (fbc->counters != NULL);
  }
7fa4cf920   Jesper Dangaard Brouer   percpu_counter.h:...
86
  #else /* !CONFIG_SMP */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
  
  struct percpu_counter {
0216bfcff   Mingming Cao   [PATCH] percpu co...
89
  	s64 count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
  };
908c7f194   Tejun Heo   percpu_counter: a...
91
92
  static inline int percpu_counter_init(struct percpu_counter *fbc, s64 amount,
  				      gfp_t gfp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  {
0216bfcff   Mingming Cao   [PATCH] percpu co...
94
  	fbc->count = amount;
833f4077b   Peter Zijlstra   lib: percpu_count...
95
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
99
100
  }
  
  static inline void percpu_counter_destroy(struct percpu_counter *fbc)
  {
  }
3a587f47b   Peter Zijlstra   lib: percpu_count...
101
102
103
104
  static inline void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
  {
  	fbc->count = amount;
  }
27f5e0f69   Tim Chen   tmpfs: add accura...
105
106
107
108
109
110
111
112
113
  static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs)
  {
  	if (fbc->count > rhs)
  		return 1;
  	else if (fbc->count < rhs)
  		return -1;
  	else
  		return 0;
  }
80188b0d7   Dave Chinner   percpu_counter: b...
114
115
116
117
118
  static inline int
  __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch)
  {
  	return percpu_counter_compare(fbc, rhs);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
  static inline void
20e897670   Peter Zijlstra   lib: make percpu_...
120
  percpu_counter_add(struct percpu_counter *fbc, s64 amount)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
123
124
125
  {
  	preempt_disable();
  	fbc->count += amount;
  	preempt_enable();
  }
0c9cf2efd   Anton Blanchard   percpu_counter: M...
126
  static inline void
104b4e513   Nikolay Borisov   percpu_counter: R...
127
  percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount, s32 batch)
0c9cf2efd   Anton Blanchard   percpu_counter: M...
128
129
130
  {
  	percpu_counter_add(fbc, amount);
  }
0216bfcff   Mingming Cao   [PATCH] percpu co...
131
  static inline s64 percpu_counter_read(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
134
  {
  	return fbc->count;
  }
c84598bbf   Shaohua Li   percpu_counter: c...
135
136
137
138
  /*
   * percpu_counter is intended to track positive numbers. In the UP case the
   * number should never be negative.
   */
0216bfcff   Mingming Cao   [PATCH] percpu co...
139
  static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
142
  {
  	return fbc->count;
  }
52d9f3b40   Peter Zijlstra   lib: percpu_count...
143
  static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
e2bab3d92   Andrew Morton   [PATCH] percpu_co...
144
145
146
  {
  	return percpu_counter_read_positive(fbc);
  }
bf1d89c81   Peter Zijlstra   lib: percpu_count...
147
148
149
150
  static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
  {
  	return percpu_counter_read(fbc);
  }
7f93cff90   Theodore Ts'o   ext4: fix kernel ...
151
152
153
154
  static inline int percpu_counter_initialized(struct percpu_counter *fbc)
  {
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
156
157
158
  #endif	/* CONFIG_SMP */
  
  static inline void percpu_counter_inc(struct percpu_counter *fbc)
  {
aa0dff2d0   Peter Zijlstra   lib: percpu_count...
159
  	percpu_counter_add(fbc, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
  }
  
  static inline void percpu_counter_dec(struct percpu_counter *fbc)
  {
aa0dff2d0   Peter Zijlstra   lib: percpu_count...
164
  	percpu_counter_add(fbc, -1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
  }
3cb4f9fa0   Peter Zijlstra   lib: percpu_count...
166
167
168
169
  static inline void percpu_counter_sub(struct percpu_counter *fbc, s64 amount)
  {
  	percpu_counter_add(fbc, -amount);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
  #endif /* _LINUX_PERCPU_COUNTER_H */