Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30-rc4 181 lines 4.6 kB view raw
1#ifndef __RES_COUNTER_H__ 2#define __RES_COUNTER_H__ 3 4/* 5 * Resource Counters 6 * Contain common data types and routines for resource accounting 7 * 8 * Copyright 2007 OpenVZ SWsoft Inc 9 * 10 * Author: Pavel Emelianov <xemul@openvz.org> 11 * 12 * See Documentation/cgroups/resource_counter.txt for more 13 * info about what this counter is. 14 */ 15 16#include <linux/cgroup.h> 17 18/* 19 * The core object. the cgroup that wishes to account for some 20 * resource may include this counter into its structures and use 21 * the helpers described beyond 22 */ 23 24struct res_counter { 25 /* 26 * the current resource consumption level 27 */ 28 unsigned long long usage; 29 /* 30 * the maximal value of the usage from the counter creation 31 */ 32 unsigned long long max_usage; 33 /* 34 * the limit that usage cannot exceed 35 */ 36 unsigned long long limit; 37 /* 38 * the number of unsuccessful attempts to consume the resource 39 */ 40 unsigned long long failcnt; 41 /* 42 * the lock to protect all of the above. 43 * the routines below consider this to be IRQ-safe 44 */ 45 spinlock_t lock; 46 /* 47 * Parent counter, used for hierarchial resource accounting 48 */ 49 struct res_counter *parent; 50}; 51 52/** 53 * Helpers to interact with userspace 54 * res_counter_read_u64() - returns the value of the specified member. 55 * res_counter_read/_write - put/get the specified fields from the 56 * res_counter struct to/from the user 57 * 58 * @counter: the counter in question 59 * @member: the field to work with (see RES_xxx below) 60 * @buf: the buffer to opeate on,... 61 * @nbytes: its size... 62 * @pos: and the offset. 63 */ 64 65u64 res_counter_read_u64(struct res_counter *counter, int member); 66 67ssize_t res_counter_read(struct res_counter *counter, int member, 68 const char __user *buf, size_t nbytes, loff_t *pos, 69 int (*read_strategy)(unsigned long long val, char *s)); 70 71typedef int (*write_strategy_fn)(const char *buf, unsigned long long *val); 72 73int res_counter_memparse_write_strategy(const char *buf, 74 unsigned long long *res); 75 76int res_counter_write(struct res_counter *counter, int member, 77 const char *buffer, write_strategy_fn write_strategy); 78 79/* 80 * the field descriptors. one for each member of res_counter 81 */ 82 83enum { 84 RES_USAGE, 85 RES_MAX_USAGE, 86 RES_LIMIT, 87 RES_FAILCNT, 88}; 89 90/* 91 * helpers for accounting 92 */ 93 94void res_counter_init(struct res_counter *counter, struct res_counter *parent); 95 96/* 97 * charge - try to consume more resource. 98 * 99 * @counter: the counter 100 * @val: the amount of the resource. each controller defines its own 101 * units, e.g. numbers, bytes, Kbytes, etc 102 * 103 * returns 0 on success and <0 if the counter->usage will exceed the 104 * counter->limit _locked call expects the counter->lock to be taken 105 */ 106 107int __must_check res_counter_charge_locked(struct res_counter *counter, 108 unsigned long val); 109int __must_check res_counter_charge(struct res_counter *counter, 110 unsigned long val, struct res_counter **limit_fail_at); 111 112/* 113 * uncharge - tell that some portion of the resource is released 114 * 115 * @counter: the counter 116 * @val: the amount of the resource 117 * 118 * these calls check for usage underflow and show a warning on the console 119 * _locked call expects the counter->lock to be taken 120 */ 121 122void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val); 123void res_counter_uncharge(struct res_counter *counter, unsigned long val); 124 125static inline bool res_counter_limit_check_locked(struct res_counter *cnt) 126{ 127 if (cnt->usage < cnt->limit) 128 return true; 129 130 return false; 131} 132 133/* 134 * Helper function to detect if the cgroup is within it's limit or 135 * not. It's currently called from cgroup_rss_prepare() 136 */ 137static inline bool res_counter_check_under_limit(struct res_counter *cnt) 138{ 139 bool ret; 140 unsigned long flags; 141 142 spin_lock_irqsave(&cnt->lock, flags); 143 ret = res_counter_limit_check_locked(cnt); 144 spin_unlock_irqrestore(&cnt->lock, flags); 145 return ret; 146} 147 148static inline void res_counter_reset_max(struct res_counter *cnt) 149{ 150 unsigned long flags; 151 152 spin_lock_irqsave(&cnt->lock, flags); 153 cnt->max_usage = cnt->usage; 154 spin_unlock_irqrestore(&cnt->lock, flags); 155} 156 157static inline void res_counter_reset_failcnt(struct res_counter *cnt) 158{ 159 unsigned long flags; 160 161 spin_lock_irqsave(&cnt->lock, flags); 162 cnt->failcnt = 0; 163 spin_unlock_irqrestore(&cnt->lock, flags); 164} 165 166static inline int res_counter_set_limit(struct res_counter *cnt, 167 unsigned long long limit) 168{ 169 unsigned long flags; 170 int ret = -EBUSY; 171 172 spin_lock_irqsave(&cnt->lock, flags); 173 if (cnt->usage <= limit) { 174 cnt->limit = limit; 175 ret = 0; 176 } 177 spin_unlock_irqrestore(&cnt->lock, flags); 178 return ret; 179} 180 181#endif