fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / linux / vserver / limit_int.h
1 #ifndef _VX_LIMIT_INT_H
2 #define _VX_LIMIT_INT_H
3
4 #include "context.h"
5
6 #ifdef  __KERNEL__
7
8 #define VXD_RCRES_COND(r)       VXD_CBIT(cres, (r))
9 #define VXD_RLIMIT_COND(r)      VXD_CBIT(limit, (r))
10
11 extern const char *vlimit_name[NUM_LIMITS];
12
13 static inline void __vx_acc_cres(struct vx_info *vxi,
14         int res, int dir, void *_data, char *_file, int _line)
15 {
16         if (VXD_RCRES_COND(res))
17                 vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
18                         (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
19                         (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
20                         (dir > 0) ? "++" : "--", _data, _file, _line);
21         if (!vxi)
22                 return;
23
24         if (dir > 0)
25                 __rlim_inc(&vxi->limit, res);
26         else
27                 __rlim_dec(&vxi->limit, res);
28 }
29
30 static inline void __vx_add_cres(struct vx_info *vxi,
31         int res, int amount, void *_data, char *_file, int _line)
32 {
33         if (VXD_RCRES_COND(res))
34                 vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
35                         (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
36                         (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
37                         amount, _data, _file, _line);
38         if (amount == 0)
39                 return;
40         if (!vxi)
41                 return;
42         __rlim_add(&vxi->limit, res, amount);
43 }
44
45 static inline
46 int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
47 {
48         int cond = (value > __rlim_rmax(limit, res));
49
50         if (cond)
51                 __rlim_rmax(limit, res) = value;
52         return cond;
53 }
54
55 static inline
56 int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
57 {
58         int cond = (value < __rlim_rmin(limit, res));
59
60         if (cond)
61                 __rlim_rmin(limit, res) = value;
62         return cond;
63 }
64
65 static inline
66 void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
67 {
68         if (!__vx_cres_adjust_max(limit, res, value))
69                 __vx_cres_adjust_min(limit, res, value);
70 }
71
72
73 /*      return values:
74          +1 ... no limit hit
75          -1 ... over soft limit
76           0 ... over hard limit         */
77
78 static inline int __vx_cres_avail(struct vx_info *vxi,
79         int res, int num, char *_file, int _line)
80 {
81         struct _vx_limit *limit;
82         rlim_t value;
83
84         if (VXD_RLIMIT_COND(res))
85                 vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
86                         (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
87                         (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
88                         (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
89                         (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
90                         num, _file, _line);
91         if (!vxi)
92                 return 1;
93
94         limit = &vxi->limit;
95         value = __rlim_get(limit, res);
96
97         if (!__vx_cres_adjust_max(limit, res, value))
98                 __vx_cres_adjust_min(limit, res, value);
99
100         if (num == 0)
101                 return 1;
102
103         if (__rlim_soft(limit, res) == RLIM_INFINITY)
104                 return -1;
105         if (value + num <= __rlim_soft(limit, res))
106                 return -1;
107
108         if (__rlim_hard(limit, res) == RLIM_INFINITY)
109                 return 1;
110         if (value + num <= __rlim_hard(limit, res))
111                 return 1;
112
113         __rlim_hit(limit, res);
114         return 0;
115 }
116
117
118 static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
119
120 static inline
121 rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
122 {
123         rlim_t value, sum = 0;
124         int res;
125
126         while ((res = *array++)) {
127                 value = __rlim_get(limit, res);
128                 __vx_cres_fixup(limit, res, value);
129                 sum += value;
130         }
131         return sum;
132 }
133
134 static inline
135 rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
136 {
137         rlim_t value = __vx_cres_array_sum(limit, array + 1);
138         int res = *array;
139
140         if (value == __rlim_get(limit, res))
141                 return value;
142
143         __rlim_set(limit, res, value);
144         /* now adjust min/max */
145         if (!__vx_cres_adjust_max(limit, res, value))
146                 __vx_cres_adjust_min(limit, res, value);
147
148         return value;
149 }
150
151 static inline int __vx_cres_array_avail(struct vx_info *vxi,
152         const int *array, int num, char *_file, int _line)
153 {
154         struct _vx_limit *limit;
155         rlim_t value = 0;
156         int res;
157
158         if (num == 0)
159                 return 1;
160         if (!vxi)
161                 return 1;
162
163         limit = &vxi->limit;
164         res = *array;
165         value = __vx_cres_array_sum(limit, array+1);
166
167         __rlim_set(limit, res, value);
168         __vx_cres_fixup(limit, res, value);
169
170         return __vx_cres_avail(vxi, res, num, _file, _line);
171 }
172
173
174 static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
175 {
176         rlim_t value;
177         int res;
178
179         /* complex resources first */
180         if ((id < 0) || (id == RLIMIT_RSS))
181                 __vx_cres_array_fixup(limit, VLA_RSS);
182
183         for (res=0; res<NUM_LIMITS; res++) {
184                 if ((id > 0) && (res != id))
185                         continue;
186
187                 value = __rlim_get(limit, res);
188                 __vx_cres_fixup(limit, res, value);
189
190                 /* not supposed to happen, maybe warn? */
191                 if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
192                         __rlim_rmax(limit, res) = __rlim_hard(limit, res);
193         }
194 }
195
196
197 #endif  /* __KERNEL__ */
198 #endif  /* _VX_LIMIT_INT_H */