Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 217 lines (187 sloc) 4.775 kb
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
1 /*
2 * resource cgroups
3 *
4 * Copyright 2007 OpenVZ SWsoft Inc
5 *
6 * Author: Pavel Emelianov <xemul@openvz.org>
7 *
8 */
9
10 #include <linux/types.h>
11 #include <linux/parser.h>
12 #include <linux/fs.h>
13 #include <linux/res_counter.h>
14 #include <linux/uaccess.h>
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
15 #include <linux/mm.h>
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
16
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
17 void res_counter_init(struct res_counter *counter, struct res_counter *parent)
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
18 {
19 spin_lock_init(&counter->lock);
c5b947b memcg: add interface to reset limits
Daisuke Nishimura authored
20 counter->limit = RESOURCE_MAX;
296c81d memory controller: soft limit interface
Balbir Singh authored
21 counter->soft_limit = RESOURCE_MAX;
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
22 counter->parent = parent;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
23 }
24
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
25 int res_counter_charge_locked(struct res_counter *counter, unsigned long val,
26 bool force)
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
27 {
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
28 int ret = 0;
29
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
30 if (counter->usage + val > counter->limit) {
31 counter->failcnt++;
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
32 ret = -ENOMEM;
33 if (!force)
34 return ret;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
35 }
36
37 counter->usage += val;
0d4dde1 Frederic Weisbecker res_counter: Account max_usage when calling res_counter_charge_nofail()
fweisbec authored
38 if (counter->usage > counter->max_usage)
c84872e Pavel Emelyanov memcgroup: add the max_usage member on the res_counter
xemul authored
39 counter->max_usage = counter->usage;
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
40 return ret;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
41 }
42
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
43 static int __res_counter_charge(struct res_counter *counter, unsigned long val,
44 struct res_counter **limit_fail_at, bool force)
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
45 {
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
46 int ret, r;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
47 unsigned long flags;
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
48 struct res_counter *c, *u;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
49
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
50 r = ret = 0;
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
51 *limit_fail_at = NULL;
52 local_irq_save(flags);
53 for (c = counter; c != NULL; c = c->parent) {
54 spin_lock(&c->lock);
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
55 r = res_counter_charge_locked(c, val, force);
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
56 spin_unlock(&c->lock);
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
57 if (r < 0 && !ret) {
58 ret = r;
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
59 *limit_fail_at = c;
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
60 if (!force)
61 break;
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
62 }
63 }
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
64
65 if (ret < 0 && !force) {
66 for (u = counter; u != c; u = u->parent) {
67 spin_lock(&u->lock);
68 res_counter_uncharge_locked(u, val);
69 spin_unlock(&u->lock);
70 }
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
71 }
72 local_irq_restore(flags);
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
73
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
74 return ret;
75 }
76
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
77 int res_counter_charge(struct res_counter *counter, unsigned long val,
78 struct res_counter **limit_fail_at)
79 {
80 return __res_counter_charge(counter, val, limit_fail_at, false);
81 }
82
0e90b31 net: introduce res_counter_charge_nofail() for socket allocations
Glauber Costa authored
83 int res_counter_charge_nofail(struct res_counter *counter, unsigned long val,
84 struct res_counter **limit_fail_at)
85 {
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
86 return __res_counter_charge(counter, val, limit_fail_at, true);
0e90b31 net: introduce res_counter_charge_nofail() for socket allocations
Glauber Costa authored
87 }
4d8438f Frederic Weisbecker res_counter: Merge res_counter_charge and res_counter_charge_nofail
fweisbec authored
88
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
89 void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val)
90 {
91 if (WARN_ON(counter->usage < val))
92 val = counter->usage;
93
94 counter->usage -= val;
95 }
96
2bb2ba9 Frederic Weisbecker rescounters: add res_counter_uncharge_until()
fweisbec authored
97 void res_counter_uncharge_until(struct res_counter *counter,
98 struct res_counter *top,
99 unsigned long val)
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
100 {
101 unsigned long flags;
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
102 struct res_counter *c;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
103
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
104 local_irq_save(flags);
2bb2ba9 Frederic Weisbecker rescounters: add res_counter_uncharge_until()
fweisbec authored
105 for (c = counter; c != top; c = c->parent) {
28dbc4b memcg: memory cgroup resource counters for hierarchy
Balbir Singh authored
106 spin_lock(&c->lock);
107 res_counter_uncharge_locked(c, val);
108 spin_unlock(&c->lock);
109 }
110 local_irq_restore(flags);
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
111 }
112
2bb2ba9 Frederic Weisbecker rescounters: add res_counter_uncharge_until()
fweisbec authored
113 void res_counter_uncharge(struct res_counter *counter, unsigned long val)
114 {
115 res_counter_uncharge_until(counter, NULL, val);
116 }
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
117
0eea103 Memory controller improve user interface
Balbir Singh authored
118 static inline unsigned long long *
119 res_counter_member(struct res_counter *counter, int member)
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
120 {
121 switch (member) {
122 case RES_USAGE:
123 return &counter->usage;
c84872e Pavel Emelyanov memcgroup: add the max_usage member on the res_counter
xemul authored
124 case RES_MAX_USAGE:
125 return &counter->max_usage;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
126 case RES_LIMIT:
127 return &counter->limit;
128 case RES_FAILCNT:
129 return &counter->failcnt;
296c81d memory controller: soft limit interface
Balbir Singh authored
130 case RES_SOFT_LIMIT:
131 return &counter->soft_limit;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
132 };
133
134 BUG();
135 return NULL;
136 }
137
138 ssize_t res_counter_read(struct res_counter *counter, int member,
0eea103 Memory controller improve user interface
Balbir Singh authored
139 const char __user *userbuf, size_t nbytes, loff_t *pos,
140 int (*read_strategy)(unsigned long long val, char *st_buf))
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
141 {
0eea103 Memory controller improve user interface
Balbir Singh authored
142 unsigned long long *val;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
143 char buf[64], *s;
144
145 s = buf;
146 val = res_counter_member(counter, member);
0eea103 Memory controller improve user interface
Balbir Singh authored
147 if (read_strategy)
148 s += read_strategy(*val, s);
149 else
150 s += sprintf(s, "%llu\n", *val);
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
151 return simple_read_from_buffer((void __user *)userbuf, nbytes,
152 pos, buf, s - buf);
153 }
154
6c191cd memcg: res_counter_read_u64(): fix potential races on 32-bit machines
KAMEZAWA Hiroyuki authored
155 #if BITS_PER_LONG == 32
156 u64 res_counter_read_u64(struct res_counter *counter, int member)
157 {
158 unsigned long flags;
159 u64 ret;
160
161 spin_lock_irqsave(&counter->lock, flags);
162 ret = *res_counter_member(counter, member);
163 spin_unlock_irqrestore(&counter->lock, flags);
164
165 return ret;
166 }
167 #else
2c7eabf CGroup API files: add res_counter_read_u64()
Paul Menage authored
168 u64 res_counter_read_u64(struct res_counter *counter, int member)
169 {
170 return *res_counter_member(counter, member);
171 }
6c191cd memcg: res_counter_read_u64(): fix potential races on 32-bit machines
KAMEZAWA Hiroyuki authored
172 #endif
2c7eabf CGroup API files: add res_counter_read_u64()
Paul Menage authored
173
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
174 int res_counter_memparse_write_strategy(const char *buf,
175 unsigned long long *res)
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
176 {
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
177 char *end;
c5b947b memcg: add interface to reset limits
Daisuke Nishimura authored
178
179 /* return RESOURCE_MAX(unlimited) if "-1" is specified */
180 if (*buf == '-') {
181 *res = simple_strtoull(buf + 1, &end, 10);
182 if (*res != 1 || *end != '\0')
183 return -EINVAL;
184 *res = RESOURCE_MAX;
185 return 0;
186 }
187
52dcf8a resource cgroups: remove bogus cast
Davidlohr Bueso authored
188 *res = memparse(buf, &end);
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
189 if (*end != '\0')
190 return -EINVAL;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
191
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
192 *res = PAGE_ALIGN(*res);
193 return 0;
194 }
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
195
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
196 int res_counter_write(struct res_counter *counter, int member,
197 const char *buf, write_strategy_fn write_strategy)
198 {
199 char *end;
200 unsigned long flags;
201 unsigned long long tmp, *val;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
202
0eea103 Memory controller improve user interface
Balbir Singh authored
203 if (write_strategy) {
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
204 if (write_strategy(buf, &tmp))
205 return -EINVAL;
0eea103 Memory controller improve user interface
Balbir Singh authored
206 } else {
207 tmp = simple_strtoull(buf, &end, 10);
208 if (*end != '\0')
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
209 return -EINVAL;
0eea103 Memory controller improve user interface
Balbir Singh authored
210 }
211 spin_lock_irqsave(&counter->lock, flags);
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
212 val = res_counter_member(counter, member);
213 *val = tmp;
0eea103 Memory controller improve user interface
Balbir Singh authored
214 spin_unlock_irqrestore(&counter->lock, flags);
856c13a cgroup files: convert res_counter_write() to be a cgroups write_string()...
Paul Menage authored
215 return 0;
e552b66 Pavel Emelyanov Memory controller: resource counters
xemul authored
216 }
Something went wrong with that request. Please try again.