2 * linux/kernel/vserver/limit.c
4 * Virtual Server: Context Limits
6 * Copyright (C) 2004-2007 Herbert Pƶtzl
8 * V0.01 broken out from vcontext V0.05
9 * V0.02 changed vcmds to vxi arg
13 #include <linux/module.h>
14 #include <linux/vs_base.h>
15 #include <linux/vs_context.h>
16 #include <linux/vs_limit.h>
17 #include <linux/vserver/switch.h>
18 #include <linux/vserver/limit_cmd.h>
20 #include <asm/errno.h>
21 #include <asm/uaccess.h>
24 const char *vlimit_name[NUM_LIMITS] = {
27 [RLIMIT_NPROC] = "NPROC",
28 [RLIMIT_NOFILE] = "NOFILE",
29 [RLIMIT_MEMLOCK] = "VML",
31 [RLIMIT_LOCKS] = "LOCKS",
32 [RLIMIT_SIGPENDING] = "SIGP",
33 [RLIMIT_MSGQUEUE] = "MSGQ",
35 [VLIMIT_NSOCK] = "NSOCK",
36 [VLIMIT_OPENFD] = "OPENFD",
37 [VLIMIT_ANON] = "ANON",
38 [VLIMIT_SHMEM] = "SHMEM",
39 [VLIMIT_DENTRY] = "DENTRY",
42 EXPORT_SYMBOL_GPL(vlimit_name);
44 #define MASK_ENTRY(x) (1 << (x))
46 const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
50 MASK_ENTRY( RLIMIT_RSS ) |
51 MASK_ENTRY( VLIMIT_ANON ) |
54 MASK_ENTRY( RLIMIT_RSS ) |
55 MASK_ENTRY( RLIMIT_NPROC ) |
56 MASK_ENTRY( RLIMIT_NOFILE ) |
57 MASK_ENTRY( RLIMIT_MEMLOCK ) |
58 MASK_ENTRY( RLIMIT_AS ) |
59 MASK_ENTRY( RLIMIT_LOCKS ) |
60 MASK_ENTRY( RLIMIT_MSGQUEUE ) |
62 MASK_ENTRY( VLIMIT_NSOCK ) |
63 MASK_ENTRY( VLIMIT_OPENFD ) |
64 MASK_ENTRY( VLIMIT_ANON ) |
65 MASK_ENTRY( VLIMIT_SHMEM ) |
66 MASK_ENTRY( VLIMIT_DENTRY ) |
70 uint32_t account_mask =
71 MASK_ENTRY( VLIMIT_SEMARY ) |
72 MASK_ENTRY( VLIMIT_NSEMS ) |
73 MASK_ENTRY( VLIMIT_MAPPED ) |
77 static int is_valid_vlimit(int id)
79 uint32_t mask = vlimit_mask.minimum |
80 vlimit_mask.softlimit | vlimit_mask.maximum;
81 return mask & (1 << id);
84 static int is_accounted_vlimit(int id)
86 if (is_valid_vlimit(id))
88 return account_mask & (1 << id);
92 static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
94 rlim_t limit = __rlim_soft(&vxi->limit, id);
95 return VX_VLIM(limit);
98 static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
100 rlim_t limit = __rlim_hard(&vxi->limit, id);
101 return VX_VLIM(limit);
104 static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
105 uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
107 if (!is_valid_vlimit(id))
111 *minimum = CRLIM_UNSET;
113 *softlimit = vc_get_soft(vxi, id);
115 *maximum = vc_get_hard(vxi, id);
119 int vc_get_rlimit(struct vx_info *vxi, void __user *data)
121 struct vcmd_ctx_rlimit_v0 vc_data;
124 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
127 ret = do_get_rlimit(vxi, vc_data.id,
128 &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
132 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
137 static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
138 uint64_t minimum, uint64_t softlimit, uint64_t maximum)
140 if (!is_valid_vlimit(id))
143 if (maximum != CRLIM_KEEP)
144 __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
145 if (softlimit != CRLIM_KEEP)
146 __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
148 /* clamp soft limit */
149 if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
150 __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
155 int vc_set_rlimit(struct vx_info *vxi, void __user *data)
157 struct vcmd_ctx_rlimit_v0 vc_data;
159 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
162 return do_set_rlimit(vxi, vc_data.id,
163 vc_data.minimum, vc_data.softlimit, vc_data.maximum);
166 #ifdef CONFIG_IA32_EMULATION
168 int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
170 struct vcmd_ctx_rlimit_v0_x32 vc_data;
172 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
175 return do_set_rlimit(vxi, vc_data.id,
176 vc_data.minimum, vc_data.softlimit, vc_data.maximum);
179 int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
181 struct vcmd_ctx_rlimit_v0_x32 vc_data;
184 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
187 ret = do_get_rlimit(vxi, vc_data.id,
188 &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
192 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
197 #endif /* CONFIG_IA32_EMULATION */
200 int vc_get_rlimit_mask(uint32_t id, void __user *data)
202 if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
208 static inline void vx_reset_minmax(struct _vx_limit *limit)
213 for (lim=0; lim<NUM_LIMITS; lim++) {
214 value = __rlim_get(limit, lim);
215 __rlim_rmax(limit, lim) = value;
216 __rlim_rmin(limit, lim) = value;
221 int vc_reset_minmax(struct vx_info *vxi, void __user *data)
223 vx_reset_minmax(&vxi->limit);
228 int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
230 struct vcmd_rlimit_stat_v0 vc_data;
231 struct _vx_limit *limit = &vxi->limit;
234 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
238 if (!is_accounted_vlimit(id))
241 vx_limit_fixup(limit, id);
242 vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
243 vc_data.value = __rlim_get(limit, id);
244 vc_data.minimum = __rlim_rmin(limit, id);
245 vc_data.maximum = __rlim_rmax(limit, id);
247 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
253 void vx_vsi_meminfo(struct sysinfo *val)
255 struct vx_info *vxi = current->vx_info;
256 unsigned long totalram, freeram;
259 /* we blindly accept the max */
260 v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
261 totalram = (v != RLIM_INFINITY) ? v : val->totalram;
263 /* total minus used equals free */
264 v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
265 freeram = (v < totalram) ? totalram - v : 0;
267 val->totalram = totalram;
268 val->freeram = freeram;
275 void vx_vsi_swapinfo(struct sysinfo *val)
277 struct vx_info *vxi = current->vx_info;
278 unsigned long totalswap, freeswap;
281 v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
282 if (v == RLIM_INFINITY) {
283 val->freeswap = val->totalswap;
287 /* we blindly accept the max */
288 w = __rlim_hard(&vxi->limit, RLIMIT_RSS);
289 totalswap = (w != RLIM_INFINITY) ? (w - v) : val->totalswap;
291 /* currently 'used' swap */
292 w = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
293 w -= (w > v) ? v : w;
295 /* total minus used equals free */
296 freeswap = (w < totalswap) ? totalswap - w : 0;
298 val->totalswap = totalswap;
299 val->freeswap = freeswap;
304 unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm)
306 struct vx_info *vxi = mm->mm_vx_info;
307 unsigned long points;
313 v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
314 w = __rlim_soft(&vxi->limit, RLIMIT_RSS);
315 points = (v > w) ? (v - w) : 0;