Blame view
include/linux/res_counter.h
5.33 KB
e552b6617
|
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
|
12 |
* See Documentation/cgroups/resource_counter.txt for more |
faebe9fdf
|
13 |
* info about what this counter is. |
e552b6617
|
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
|
28 |
unsigned long long usage; |
e552b6617
|
29 |
/* |
c84872e16
|
30 31 32 33 |
* the maximal value of the usage from the counter creation */ unsigned long long max_usage; /* |
e552b6617
|
34 35 |
* the limit that usage cannot exceed */ |
0eea10301
|
36 |
unsigned long long limit; |
e552b6617
|
37 |
/* |
296c81d89
|
38 39 40 41 |
* the limit that usage can be exceed */ unsigned long long soft_limit; /* |
e552b6617
|
42 43 |
* the number of unsuccessful attempts to consume the resource */ |
0eea10301
|
44 |
unsigned long long failcnt; |
e552b6617
|
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
|
50 51 52 53 |
/* * Parent counter, used for hierarchial resource accounting */ struct res_counter *parent; |
e552b6617
|
54 |
}; |
c5b947b28
|
55 |
#define RESOURCE_MAX (unsigned long long)LLONG_MAX |
2c7eabf37
|
56 |
/** |
e552b6617
|
57 |
* Helpers to interact with userspace |
2c7eabf37
|
58 |
* res_counter_read_u64() - returns the value of the specified member. |
e552b6617
|
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
|
68 |
u64 res_counter_read_u64(struct res_counter *counter, int member); |
e552b6617
|
69 |
ssize_t res_counter_read(struct res_counter *counter, int member, |
0eea10301
|
70 71 |
const char __user *buf, size_t nbytes, loff_t *pos, int (*read_strategy)(unsigned long long val, char *s)); |
856c13aa1
|
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
|
80 81 82 83 84 85 86 |
/* * the field descriptors. one for each member of res_counter */ enum { RES_USAGE, |
c84872e16
|
87 |
RES_MAX_USAGE, |
e552b6617
|
88 89 |
RES_LIMIT, RES_FAILCNT, |
296c81d89
|
90 |
RES_SOFT_LIMIT, |
e552b6617
|
91 92 93 94 95 |
}; /* * helpers for accounting */ |
28dbc4b6a
|
96 |
void res_counter_init(struct res_counter *counter, struct res_counter *parent); |
e552b6617
|
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
|
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
|
111 |
unsigned long val, struct res_counter **limit_fail_at); |
e552b6617
|
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
|
124 |
void res_counter_uncharge(struct res_counter *counter, unsigned long val); |
e552b6617
|
125 |
|
9d11ea9f1
|
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
|
134 |
{ |
9d11ea9f1
|
135 136 |
unsigned long long margin; unsigned long flags; |
296c81d89
|
137 |
|
9d11ea9f1
|
138 139 140 141 |
spin_lock_irqsave(&cnt->lock, flags); margin = cnt->limit - cnt->usage; spin_unlock_irqrestore(&cnt->lock, flags); return margin; |
296c81d89
|
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
|
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
|
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
|
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
|
189 |
if (cnt->usage <= limit) { |
12b980441
|
190 191 192 193 194 195 |
cnt->limit = limit; ret = 0; } spin_unlock_irqrestore(&cnt->lock, flags); return ret; } |
296c81d89
|
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
|
207 |
#endif |