diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/include/linux/vs_context.h linux-2.6.22.9-vs2.3.0.25.2/include/linux/vs_context.h --- linux-2.6.22.9-vs2.3.0.25.1/include/linux/vs_context.h 2007-09-30 16:08:46 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/include/linux/vs_context.h 2007-10-01 11:50:10 +0200 @@ -166,6 +164,7 @@ static inline struct vx_info *__task_get task_lock(p); vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)", p, _file, _line); + __get_xid_other(p->vx_info ? p->vx_info->vx_id : 0); vxi = __get_vx_info(p->vx_info, _file, _line, _here); task_unlock(p); return vxi; diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/include/linux/vserver/debug.h linux-2.6.22.9-vs2.3.0.25.2/include/linux/vserver/debug.h --- linux-2.6.22.9-vs2.3.0.25.1/include/linux/vserver/debug.h 2007-08-05 20:53:13 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/include/linux/vserver/debug.h 2007-10-01 12:10:42 +0200 @@ -109,5 +109,63 @@ void dump_vx_info_inactive(int); #define vxd_assert(c, f, x...) do { } while (0) #endif +/* FIXME: HACK FOR TESTING */ + +#include + +struct _vxrc { + atomic_t mm_ref; + atomic_t task_ref; + atomic_t sock_ref; + atomic_t timer_ref; + atomic_t other_ref; +}; + +extern struct _vxrc VXRC[256]; + + +#define xid_ref(i,n) VXRC[(i) & 0xFF].n ## _ref + +#define __get_xid_mm(i) \ + __get_xid(i, &xid_ref(i, mm), __FILE__, __LINE__, __HERE__) +#define __get_xid_task(i) \ + __get_xid(i, &xid_ref(i, task), __FILE__, __LINE__, __HERE__) +#define __get_xid_sock(i) \ + __get_xid(i, &xid_ref(i, sock), __FILE__, __LINE__, __HERE__) +#define __get_xid_timer(i) \ + __get_xid(i, &xid_ref(i, timer), __FILE__, __LINE__, __HERE__) +#define __get_xid_other(i) \ + __get_xid(i, &xid_ref(i, other), __FILE__, __LINE__, __HERE__) + +static inline void __get_xid(int i, atomic_t *ref, + const char *_file, int _line, void *_here) +{ + atomic_inc(ref); +} + +#define __put_xid_mm(i) \ + __put_xid(i, &xid_ref(i, mm), __FILE__, __LINE__, __HERE__) +#define __put_xid_task(i) \ + __put_xid(i, &xid_ref(i, task), __FILE__, __LINE__, __HERE__) +#define __put_xid_sock(i) \ + __put_xid(i, &xid_ref(i, sock), __FILE__, __LINE__, __HERE__) +#define __put_xid_timer(i) \ + __put_xid(i, &xid_ref(i, timer), __FILE__, __LINE__, __HERE__) +#define __put_xid_other(i) \ + __put_xid(i, &xid_ref(i, other), __FILE__, __LINE__, __HERE__) + +static inline void __put_xid(int i, atomic_t *ref, + const char *_file, int _line, void *_here) +{ + int val = atomic_dec_return(ref); + + if (i == 0) + return; + vxlprintk((val == 0), "put_xid(#%d) ZERO", i, _file, _line); + vxlprintk((val < 0), "put_xid(#%d) val=%d", i, val, _file, _line); +} + + +/* FIXME: HACK FOR TESTING */ #endif /* _VX_DEBUG_H */ diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/ipc/mqueue.c linux-2.6.22.9-vs2.3.0.25.2/ipc/mqueue.c --- linux-2.6.22.9-vs2.3.0.25.1/ipc/mqueue.c 2007-08-05 20:53:13 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/ipc/mqueue.c 2007-10-01 11:57:43 +0200 @@ -269,6 +269,7 @@ static void mqueue_delete_inode(struct i vx_ipcmsg_sub(vxi, user, mq_bytes); queues_count--; spin_unlock(&mq_lock); + __put_xid_other(vxi ? vxi->vx_id : 0); put_vx_info(vxi); free_uid(user); } diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/ipc/shm.c linux-2.6.22.9-vs2.3.0.25.2/ipc/shm.c --- linux-2.6.22.9-vs2.3.0.25.1/ipc/shm.c 2007-08-11 22:41:51 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/ipc/shm.c 2007-10-01 11:58:06 +0200 @@ -202,6 +202,7 @@ static void shm_destroy(struct ipc_names shp->mlock_user); fput (shp->shm_file); security_shm_free(shp); + __put_xid_other(vxi ? vxi->vx_id : 0); put_vx_info(vxi); ipc_rcu_putref(shp); } diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/kernel/fork.c linux-2.6.22.9-vs2.3.0.25.2/kernel/fork.c --- linux-2.6.22.9-vs2.3.0.25.1/kernel/fork.c 2007-09-29 19:48:50 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/kernel/fork.c 2007-10-01 12:00:55 +0200 @@ -113,6 +113,7 @@ void free_task(struct task_struct *tsk) { free_thread_info(tsk->stack); rt_mutex_debug_task_free(tsk); + __put_xid_task(tsk->vx_info ? tsk->vx_info->vx_id : 0); clr_vx_info(&tsk->vx_info); clr_nx_info(&tsk->nx_info); free_task_struct(tsk); @@ -354,6 +355,7 @@ static struct mm_struct * mm_init(struct if (likely(!mm_alloc_pgd(mm))) { mm->def_flags = 0; + __get_xid_mm(vxi ? vxi->vx_id : 0); set_vx_info(&mm->mm_vx_info, vxi); return mm; } @@ -386,6 +388,7 @@ void fastcall __mmdrop(struct mm_struct BUG_ON(mm == &init_mm); mm_free_pgd(mm); destroy_context(mm); + __put_xid_mm(mm->mm_vx_info ? mm->mm_vx_info->vx_id : 0); clr_vx_info(&mm->mm_vx_info); free_mm(mm); } @@ -533,6 +536,7 @@ fail_nocontext: * If init_new_context() failed, we cannot use mmput() to free the mm * because it calls destroy_context() */ + __put_xid_mm(mm->mm_vx_info ? mm->mm_vx_info->vx_id : 0); clr_vx_info(&mm->mm_vx_info); mm_free_pgd(mm); free_mm(mm); diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/kernel/posix-timers.c linux-2.6.22.9-vs2.3.0.25.2/kernel/posix-timers.c --- linux-2.6.22.9-vs2.3.0.25.1/kernel/posix-timers.c 2007-08-05 20:53:13 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/kernel/posix-timers.c 2007-10-01 11:52:11 +0200 @@ -301,6 +301,8 @@ int posix_timer_event(struct k_itimer *t struct vx_info_save vxis; int ret; + __get_xid_timer(timr->it_process->vx_info ? + timr->it_process->vx_info->vx_id : 0); enter_vx_info(task_get_vx_info(timr->it_process), &vxis); memset(&timr->sigq->info, 0, sizeof(siginfo_t)); timr->sigq->info.si_sys_private = si_private; @@ -330,6 +332,7 @@ int posix_timer_event(struct k_itimer *t timr->it_process); out: leave_vx_info(&vxis); + __put_xid_timer(vxis.vxi ? vxis.vxi->vx_id : 0); put_vx_info(vxis.vxi); return ret; } diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/kernel/vserver/context.c linux-2.6.22.9-vs2.3.0.25.2/kernel/vserver/context.c --- linux-2.6.22.9-vs2.3.0.25.1/kernel/vserver/context.c 2007-09-30 14:00:50 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/kernel/vserver/context.c 2007-10-01 12:41:05 +0200 @@ -338,6 +338,7 @@ static struct vx_info *__create_vx_info( vxdprintk(VXD_CBIT(xid, 0), "create_vx_info(%d) = %p (new)", id, new); claim_vx_info(new, NULL); + __get_xid_task(new->vx_id); __hash_vx_info(get_vx_info(new)); vxi = new, new = NULL; @@ -373,10 +374,12 @@ struct vx_info *lookup_vx_info(int id) struct vx_info *vxi = NULL; if (id < 0) { + __get_xid_other(current->vx_info ? current->vx_info->vx_id : 0); vxi = get_vx_info(current->vx_info); } else if (id > 1) { spin_lock(&vx_info_hash_lock); vxi = get_vx_info(__lookup_vx_info(id)); + __get_xid_other(vxi ? vxi->vx_id : 0); spin_unlock(&vx_info_hash_lock); } return vxi; @@ -571,9 +574,11 @@ int vx_migrate_task(struct task_struct * if (old_vxi) { release_vx_info(old_vxi, p); + __put_xid_task(old_vxi ? old_vxi->vx_id : 0); clr_vx_info(&p->vx_info); } claim_vx_info(vxi, p); + __get_xid_task(vxi ? vxi->vx_id : 0); set_vx_info(&p->vx_info, vxi); p->xid = vxi->vx_id; @@ -600,6 +605,7 @@ int vx_migrate_task(struct task_struct * } } out: + __put_xid_other(old_vxi ? old_vxi->vx_id : 0); put_vx_info(old_vxi); return ret; } @@ -656,6 +662,7 @@ void vx_set_persistent(struct vx_info *v vxdprintk(VXD_CBIT(xid, 6), "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id); + __get_xid_task(vxi->vx_id); get_vx_info(vxi); claim_vx_info(vxi, NULL); } @@ -666,6 +673,7 @@ void vx_clear_persistent(struct vx_info "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id); release_vx_info(vxi, NULL); + __put_xid_task(vxi->vx_id); put_vx_info(vxi); } @@ -771,6 +779,7 @@ int vc_ctx_create(uint32_t xid, void __u return -EINVAL; new_vxi = __create_vx_info(xid); + __get_xid_task(xid); if (IS_ERR(new_vxi)) return PTR_ERR(new_vxi); @@ -793,6 +802,7 @@ int vc_ctx_create(uint32_t xid, void __u vx_set_persistent(new_vxi); out: release_vx_info(new_vxi, NULL); + __put_xid_task(new_vxi->vx_id); put_vx_info(new_vxi); return ret; } diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/kernel/vserver/debug.c linux-2.6.22.9-vs2.3.0.25.2/kernel/vserver/debug.c --- linux-2.6.22.9-vs2.3.0.25.1/kernel/vserver/debug.c 2007-08-15 22:01:52 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/kernel/vserver/debug.c 2007-10-01 10:18:38 +0200 @@ -30,3 +30,9 @@ void dump_vx_info(struct vx_info *vxi, i EXPORT_SYMBOL_GPL(dump_vx_info); + +/* FIXME: HACK FOR TESTING */ + +struct _vxrc VXRC[256] = { }; + +/* FIXME: HACK FOR TESTING */ diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/kernel/vserver/proc.c linux-2.6.22.9-vs2.3.0.25.2/kernel/vserver/proc.c --- linux-2.6.22.9-vs2.3.0.25.1/kernel/vserver/proc.c 2007-09-21 09:57:50 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/kernel/vserver/proc.c 2007-10-01 12:10:14 +0200 @@ -73,6 +73,26 @@ static int proc_virtual_status(char *buf atomic_read(&vs_global_ipc_ns)); } +static int proc_virtual_vxrc(char *buffer) +{ + int length = 0; + int i; + + for (i = 0; i < 256; i++) { + int mm_ref = atomic_read(&VXRC[i].mm_ref); + int task_ref = atomic_read(&VXRC[i].task_ref); + int sock_ref = atomic_read(&VXRC[i].sock_ref); + int timer_ref = atomic_read(&VXRC[i].timer_ref); + int other_ref = atomic_read(&VXRC[i].other_ref); + + if (!(mm_ref | task_ref | sock_ref)) + continue; + length += sprintf(buffer + length, + "[%d]\t%d\t%d\t%d\t%d\t%d\n", + i, mm_ref, task_ref, sock_ref, timer_ref, other_ref); + } + return length; +} int proc_vxi_info(struct vx_info *vxi, char *buffer) { @@ -428,6 +448,7 @@ static ssize_t proc_vx_info_read(struct free_page(page); out_put: + __put_xid_other(vxi->vx_id); put_vx_info(vxi); out: return length; @@ -720,6 +741,7 @@ static struct inode_operations proc_xid_ static struct vs_entry vx_virtual_stuff[] = { INF("info", S_IRUGO, virtual_info), INF("status", S_IRUGO, virtual_status), + INF("vxrc", S_IRUGO, virtual_vxrc), DIR(NULL, S_IRUGO | S_IXUGO, xid), }; @@ -1011,6 +1033,7 @@ int proc_pid_vx_info(struct task_struct (unsigned long long)vxi->vx_flags); buffer += sprintf(buffer, "CIPid:\t%d\n", vxi->vx_initpid); + __put_xid_other(vxi->vx_id); put_vx_info(vxi); out: return buffer - orig; diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/kernel/vserver/switch.c linux-2.6.22.9-vs2.3.0.25.2/kernel/vserver/switch.c --- linux-2.6.22.9-vs2.3.0.25.1/kernel/vserver/switch.c 2007-08-19 06:11:43 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/kernel/vserver/switch.c 2007-10-01 12:00:12 +0200 @@ -489,8 +489,10 @@ out_nxi: if ((args & VCA_NXI) && nxi) put_nx_info(nxi); out_vxi: - if ((args & VCA_VXI) && vxi) + if ((args & VCA_VXI) && vxi) { + __put_xid_other(vxi->vx_id); put_vx_info(vxi); + } out: vxdprintk(VXD_CBIT(switch, 1), "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]", diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.25.1/net/core/sock.c linux-2.6.22.9-vs2.3.0.25.2/net/core/sock.c --- linux-2.6.22.9-vs2.3.0.25.1/net/core/sock.c 2007-08-05 20:53:13 +0200 +++ linux-2.6.22.9-vs2.3.0.25.2/net/core/sock.c 2007-10-01 11:49:04 +0200 @@ -917,6 +917,7 @@ void sk_free(struct sock *sk) security_sk_free(sk); vx_sock_dec(sk); + __put_xid_sock(sk->sk_vx_info ? sk->sk_vx_info->vx_id : 0); clr_vx_info(&sk->sk_vx_info); sk->sk_xid = -1; clr_nx_info(&sk->sk_nx_info); @@ -985,6 +986,7 @@ struct sock *sk_clone(const struct sock newsk->sk_priority = 0; atomic_set(&newsk->sk_refcnt, 2); + __get_xid_sock(sk->sk_vx_info ? sk->sk_vx_info->vx_id : 0); set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info); newsk->sk_xid = sk->sk_xid; vx_sock_inc(newsk); @@ -1573,6 +1575,7 @@ void sock_init_data(struct socket *sock, sk->sk_stamp = ktime_set(-1L, -1L); + __get_xid_sock(current->vx_info ? current->vx_info->vx_id : 0); set_vx_info(&sk->sk_vx_info, current->vx_info); sk->sk_xid = vx_current_xid(); vx_sock_inc(sk);