Blame view

include/linux/res_counter.h 5.33 KB
e552b6617   Pavel Emelianov   Memory controller...
1
2
3
4
5
6
7
8
9
10
11
  #ifndef __RES_COUNTER_H__
  #define __RES_COUNTER_H__
  
  /*
   * Resource Counters
   * Contain common data types and routines for resource accounting
   *
   * Copyright 2007 OpenVZ SWsoft Inc
   *
   * Author: Pavel Emelianov <xemul@openvz.org>
   *
45ce80fb6   Li Zefan   cgroups: consolid...
12
   * See Documentation/cgroups/resource_counter.txt for more
faebe9fdf   Pavel Emelyanov   memcgroups: add a...
13
   * info about what this counter is.
e552b6617   Pavel Emelianov   Memory controller...
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   */
  
  #include <linux/cgroup.h>
  
  /*
   * The core object. the cgroup that wishes to account for some
   * resource may include this counter into its structures and use
   * the helpers described beyond
   */
  
  struct res_counter {
  	/*
  	 * the current resource consumption level
  	 */
0eea10301   Balbir Singh   Memory controller...
28
  	unsigned long long usage;
e552b6617   Pavel Emelianov   Memory controller...
29
  	/*
c84872e16   Pavel Emelyanov   memcgroup: add th...
30
31
32
33
  	 * the maximal value of the usage from the counter creation
  	 */
  	unsigned long long max_usage;
  	/*
e552b6617   Pavel Emelianov   Memory controller...
34
35
  	 * the limit that usage cannot exceed
  	 */
0eea10301   Balbir Singh   Memory controller...
36
  	unsigned long long limit;
e552b6617   Pavel Emelianov   Memory controller...
37
  	/*
296c81d89   Balbir Singh   memory controller...
38
39
40
41
  	 * the limit that usage can be exceed
  	 */
  	unsigned long long soft_limit;
  	/*
e552b6617   Pavel Emelianov   Memory controller...
42
43
  	 * the number of unsuccessful attempts to consume the resource
  	 */
0eea10301   Balbir Singh   Memory controller...
44
  	unsigned long long failcnt;
e552b6617   Pavel Emelianov   Memory controller...
45
46
47
48
49
  	/*
  	 * the lock to protect all of the above.
  	 * the routines below consider this to be IRQ-safe
  	 */
  	spinlock_t lock;
28dbc4b6a   Balbir Singh   memcg: memory cgr...
50
51
52
53
  	/*
  	 * Parent counter, used for hierarchial resource accounting
  	 */
  	struct res_counter *parent;
e552b6617   Pavel Emelianov   Memory controller...
54
  };
c5b947b28   Daisuke Nishimura   memcg: add interf...
55
  #define RESOURCE_MAX (unsigned long long)LLONG_MAX
2c7eabf37   Paul Menage   CGroup API files:...
56
  /**
e552b6617   Pavel Emelianov   Memory controller...
57
   * Helpers to interact with userspace
2c7eabf37   Paul Menage   CGroup API files:...
58
   * res_counter_read_u64() - returns the value of the specified member.
e552b6617   Pavel Emelianov   Memory controller...
59
60
61
62
63
64
65
66
67
   * res_counter_read/_write - put/get the specified fields from the
   * res_counter struct to/from the user
   *
   * @counter:     the counter in question
   * @member:  the field to work with (see RES_xxx below)
   * @buf:     the buffer to opeate on,...
   * @nbytes:  its size...
   * @pos:     and the offset.
   */
2c7eabf37   Paul Menage   CGroup API files:...
68
  u64 res_counter_read_u64(struct res_counter *counter, int member);
e552b6617   Pavel Emelianov   Memory controller...
69
  ssize_t res_counter_read(struct res_counter *counter, int member,
0eea10301   Balbir Singh   Memory controller...
70
71
  		const char __user *buf, size_t nbytes, loff_t *pos,
  		int (*read_strategy)(unsigned long long val, char *s));
856c13aa1   Paul Menage   cgroup files: con...
72
73
74
75
76
77
78
79
  
  typedef int (*write_strategy_fn)(const char *buf, unsigned long long *val);
  
  int res_counter_memparse_write_strategy(const char *buf,
  					unsigned long long *res);
  
  int res_counter_write(struct res_counter *counter, int member,
  		      const char *buffer, write_strategy_fn write_strategy);
e552b6617   Pavel Emelianov   Memory controller...
80
81
82
83
84
85
86
  
  /*
   * the field descriptors. one for each member of res_counter
   */
  
  enum {
  	RES_USAGE,
c84872e16   Pavel Emelyanov   memcgroup: add th...
87
  	RES_MAX_USAGE,
e552b6617   Pavel Emelianov   Memory controller...
88
89
  	RES_LIMIT,
  	RES_FAILCNT,
296c81d89   Balbir Singh   memory controller...
90
  	RES_SOFT_LIMIT,
e552b6617   Pavel Emelianov   Memory controller...
91
92
93
94
95
  };
  
  /*
   * helpers for accounting
   */
28dbc4b6a   Balbir Singh   memcg: memory cgr...
96
  void res_counter_init(struct res_counter *counter, struct res_counter *parent);
e552b6617   Pavel Emelianov   Memory controller...
97
98
99
100
101
102
103
104
105
106
107
  
  /*
   * charge - try to consume more resource.
   *
   * @counter: the counter
   * @val: the amount of the resource. each controller defines its own
   *       units, e.g. numbers, bytes, Kbytes, etc
   *
   * returns 0 on success and <0 if the counter->usage will exceed the
   * counter->limit _locked call expects the counter->lock to be taken
   */
f2992db2a   Pavel Emelyanov   Mark res_counter_...
108
109
110
  int __must_check res_counter_charge_locked(struct res_counter *counter,
  		unsigned long val);
  int __must_check res_counter_charge(struct res_counter *counter,
4e649152c   KAMEZAWA Hiroyuki   memcg: some modif...
111
  		unsigned long val, struct res_counter **limit_fail_at);
e552b6617   Pavel Emelianov   Memory controller...
112
113
114
115
116
117
118
119
120
121
122
123
  
  /*
   * uncharge - tell that some portion of the resource is released
   *
   * @counter: the counter
   * @val: the amount of the resource
   *
   * these calls check for usage underflow and show a warning on the console
   * _locked call expects the counter->lock to be taken
   */
  
  void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val);
4e649152c   KAMEZAWA Hiroyuki   memcg: some modif...
124
  void res_counter_uncharge(struct res_counter *counter, unsigned long val);
e552b6617   Pavel Emelianov   Memory controller...
125

9d11ea9f1   Johannes Weiner   memcg: simplify t...
126
127
128
129
130
131
132
133
  /**
   * res_counter_margin - calculate chargeable space of a counter
   * @cnt: the counter
   *
   * Returns the difference between the hard limit and the current usage
   * of resource counter @cnt.
   */
  static inline unsigned long long res_counter_margin(struct res_counter *cnt)
296c81d89   Balbir Singh   memory controller...
134
  {
9d11ea9f1   Johannes Weiner   memcg: simplify t...
135
136
  	unsigned long long margin;
  	unsigned long flags;
296c81d89   Balbir Singh   memory controller...
137

9d11ea9f1   Johannes Weiner   memcg: simplify t...
138
139
140
141
  	spin_lock_irqsave(&cnt->lock, flags);
  	margin = cnt->limit - cnt->usage;
  	spin_unlock_irqrestore(&cnt->lock, flags);
  	return margin;
296c81d89   Balbir Singh   memory controller...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  }
  
  /**
   * Get the difference between the usage and the soft limit
   * @cnt: The counter
   *
   * Returns 0 if usage is less than or equal to soft limit
   * The difference between usage and soft limit, otherwise.
   */
  static inline unsigned long long
  res_counter_soft_limit_excess(struct res_counter *cnt)
  {
  	unsigned long long excess;
  	unsigned long flags;
  
  	spin_lock_irqsave(&cnt->lock, flags);
  	if (cnt->usage <= cnt->soft_limit)
  		excess = 0;
  	else
  		excess = cnt->usage - cnt->soft_limit;
  	spin_unlock_irqrestore(&cnt->lock, flags);
  	return excess;
  }
c84872e16   Pavel Emelyanov   memcgroup: add th...
165
166
167
168
169
170
171
172
  static inline void res_counter_reset_max(struct res_counter *cnt)
  {
  	unsigned long flags;
  
  	spin_lock_irqsave(&cnt->lock, flags);
  	cnt->max_usage = cnt->usage;
  	spin_unlock_irqrestore(&cnt->lock, flags);
  }
29f2a4dac   Pavel Emelyanov   memcgroup: implem...
173
174
175
176
177
178
179
180
  static inline void res_counter_reset_failcnt(struct res_counter *cnt)
  {
  	unsigned long flags;
  
  	spin_lock_irqsave(&cnt->lock, flags);
  	cnt->failcnt = 0;
  	spin_unlock_irqrestore(&cnt->lock, flags);
  }
12b980441   KAMEZAWA Hiroyuki   res_counter: limi...
181
182
183
184
185
186
187
188
  
  static inline int res_counter_set_limit(struct res_counter *cnt,
  		unsigned long long limit)
  {
  	unsigned long flags;
  	int ret = -EBUSY;
  
  	spin_lock_irqsave(&cnt->lock, flags);
11d55d2cb   Li Zefan   res_counter: fix ...
189
  	if (cnt->usage <= limit) {
12b980441   KAMEZAWA Hiroyuki   res_counter: limi...
190
191
192
193
194
195
  		cnt->limit = limit;
  		ret = 0;
  	}
  	spin_unlock_irqrestore(&cnt->lock, flags);
  	return ret;
  }
296c81d89   Balbir Singh   memory controller...
196
197
198
199
200
201
202
203
204
205
206
  static inline int
  res_counter_set_soft_limit(struct res_counter *cnt,
  				unsigned long long soft_limit)
  {
  	unsigned long flags;
  
  	spin_lock_irqsave(&cnt->lock, flags);
  	cnt->soft_limit = soft_limit;
  	spin_unlock_irqrestore(&cnt->lock, flags);
  	return 0;
  }
e552b6617   Pavel Emelianov   Memory controller...
207
  #endif