diff -NurpP --minimal linux-2.6.11.10-vs2.0/include/linux/vs_context.h linux-2.6.11.10-vs2.0-p1/include/linux/vs_context.h --- linux-2.6.11.10-vs2.0/include/linux/vs_context.h 2005-05-21 04:29:23 +0200 +++ linux-2.6.11.10-vs2.0-p1/include/linux/vs_context.h 2005-05-22 14:58:04 +0200 @@ -28,10 +28,12 @@ extern void free_vx_info(struct vx_info #define put_vx_info(i) __put_vx_info(i,__FILE__,__LINE__) -static inline void __put_vx_info(struct vx_info *vxi, const char *_file, int _line) +static inline void __put_vx_info(struct vx_info *vxi, + const char *_file, int _line) { if (!vxi) return; + vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])", vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0, _file, _line); @@ -45,7 +47,7 @@ static inline void __put_vx_info(struct #define init_vx_info(p,i) __init_vx_info(p,i,__FILE__,__LINE__) static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi, - const char *_file, int _line) + const char *_file, int _line) { if (vxi) { vxlprintk(VXD_CBIT(xid, 3), diff -NurpP --minimal linux-2.6.11.10-vs2.0/include/linux/vs_network.h linux-2.6.11.10-vs2.0-p1/include/linux/vs_network.h --- linux-2.6.11.10-vs2.0/include/linux/vs_network.h 2005-05-21 04:29:23 +0200 +++ linux-2.6.11.10-vs2.0-p1/include/linux/vs_network.h 2005-05-22 14:58:04 +0200 @@ -13,9 +13,11 @@ static inline struct nx_info *__get_nx_i { if (!nxi) return NULL; + vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])", nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0, _file, _line); + atomic_inc(&nxi->nx_usecnt); return nxi; } @@ -29,9 +31,11 @@ static inline void __put_nx_info(struct { if (!nxi) return; + vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])", nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0, _file, _line); + if (atomic_dec_and_test(&nxi->nx_usecnt)) free_nx_info(nxi); } @@ -89,9 +93,9 @@ static __inline__ struct nx_info *__task struct nx_info *nxi; task_lock(p); - nxi = __get_nx_info(p->nx_info, _file, _line); vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)", p, _file, _line); + nxi = __get_nx_info(p->nx_info, _file, _line); task_unlock(p); return nxi; } diff -NurpP --minimal linux-2.6.11.10-vs2.0/include/linux/vserver/context.h linux-2.6.11.10-vs2.0-p1/include/linux/vserver/context.h --- linux-2.6.11.10-vs2.0/include/linux/vserver/context.h 2005-05-21 04:29:23 +0200 +++ linux-2.6.11.10-vs2.0-p1/include/linux/vserver/context.h 2005-05-22 14:58:04 +0200 @@ -81,7 +81,7 @@ enum { struct vx_info { struct hlist_node vx_hlist; /* linked list of contexts */ - struct rcu_head vx_rcu; /* the rcu head */ +// struct rcu_head vx_rcu; /* the rcu head */ xid_t vx_id; /* context id */ atomic_t vx_usecnt; /* usage count */ atomic_t vx_tasks; /* tasks count */ @@ -96,7 +96,7 @@ struct vx_info { pid_t vx_initpid; /* PID of fake init process */ - spinlock_t vx_lock; +// spinlock_t vx_lock; wait_queue_head_t vx_wait; /* context exit waitqueue */ struct _vx_limit limit; /* vserver limits */ @@ -114,7 +114,6 @@ struct vx_info { #define VXS_PAUSED 0x0010 #define VXS_ONHOLD 0x0020 #define VXS_SHUTDOWN 0x0100 -#define VXS_DEFUNCT 0x1000 #define VXS_RELEASED 0x8000 /* check conditions */ @@ -150,8 +149,6 @@ extern int vx_migrate_task(struct task_s extern long vs_state_change(struct vx_info *, unsigned int); -extern void free_vx_info(struct vx_info *); - #endif /* __KERNEL__ */ #else /* _VX_CONTEXT_H */ diff -NurpP --minimal linux-2.6.11.10-vs2.0/include/linux/vserver/network.h linux-2.6.11.10-vs2.0-p1/include/linux/vserver/network.h --- linux-2.6.11.10-vs2.0/include/linux/vserver/network.h 2005-05-21 04:29:23 +0200 +++ linux-2.6.11.10-vs2.0-p1/include/linux/vserver/network.h 2005-05-22 14:58:04 +0200 @@ -21,7 +21,7 @@ struct nx_info { struct hlist_node nx_hlist; /* linked list of nxinfos */ - struct rcu_head nx_rcu; /* the rcu head */ +// struct rcu_head nx_rcu; /* the rcu head */ nid_t nx_id; /* vnet id */ atomic_t nx_usecnt; /* usage count */ atomic_t nx_refcnt; /* reference count */ diff -NurpP --minimal linux-2.6.11.10-vs2.0/kernel/exit.c linux-2.6.11.10-vs2.0-p1/kernel/exit.c --- linux-2.6.11.10-vs2.0/kernel/exit.c 2005-05-21 04:29:23 +0200 +++ linux-2.6.11.10-vs2.0-p1/kernel/exit.c 2005-05-22 14:58:04 +0200 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff -NurpP --minimal linux-2.6.11.10-vs2.0/kernel/vserver/context.c linux-2.6.11.10-vs2.0-p1/kernel/vserver/context.c --- linux-2.6.11.10-vs2.0/kernel/vserver/context.c 2005-05-21 04:29:23 +0200 +++ linux-2.6.11.10-vs2.0-p1/kernel/vserver/context.c 2005-05-22 14:58:49 +0200 @@ -65,7 +65,7 @@ static struct vx_info *__alloc_vx_info(x atomic_set(&new->vx_tasks, 0); new->vx_parent = NULL; new->vx_state = 0; - new->vx_lock = SPIN_LOCK_UNLOCKED; + // new->vx_lock = SPIN_LOCK_UNLOCKED; init_waitqueue_head(&new->vx_wait); /* rest of init goes here */ @@ -74,7 +74,6 @@ static struct vx_info *__alloc_vx_info(x vx_info_init_cvirt(&new->cvirt); vx_info_init_cacct(&new->cacct); - new->vx_flags = VXF_STATE_SETUP|VXF_STATE_INIT; new->vx_bcaps = CAP_INIT_EFF_SET; new->vx_ccaps = 0; @@ -107,7 +106,7 @@ static void __dealloc_vx_info(struct vx_ kfree(vxi); } -void __shutdown_vx_info(struct vx_info *vxi) +static void __shutdown_vx_info(struct vx_info *vxi) { struct namespace *namespace; struct fs_struct *fs; @@ -131,13 +130,12 @@ void __shutdown_vx_info(struct vx_info * void free_vx_info(struct vx_info *vxi) { /* context shutdown is mandatory */ - // BUG_ON(vxi->vx_state != VXS_SHUTDOWN); + BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN)); BUG_ON(atomic_read(&vxi->vx_usecnt)); BUG_ON(atomic_read(&vxi->vx_tasks)); BUG_ON(vx_info_state(vxi, VXS_HASHED)); - // BUG_ON(!vx_state(vxi, VXS_DEFUNCT)); BUG_ON(vxi->vx_namespace); BUG_ON(vxi->vx_fs); @@ -177,7 +175,7 @@ static inline void __hash_vx_info(struct vxh_hash_vx_info(vxi); /* context must not be hashed */ - BUG_ON(vxi->vx_state & VXS_HASHED); + BUG_ON(vx_info_state(vxi, VXS_HASHED)); vxi->vx_state |= VXS_HASHED; head = &vx_info_hash[__hashval(vxi->vx_id)]; @@ -196,9 +194,8 @@ static inline void __unhash_vx_info(stru "__unhash_vx_info: %p[#%d]", vxi, vxi->vx_id); vxh_unhash_vx_info(vxi); - /* maybe warn on that? */ - if (!(vxi->vx_state & VXS_HASHED)) - return; + /* context must be hashed */ + BUG_ON(!vx_info_state(vxi, VXS_HASHED)); vxi->vx_state &= ~VXS_HASHED; hlist_del(&vxi->vx_hlist); @@ -323,7 +320,7 @@ out_unlock: /* __create_vx_info() * create the requested context - * get() it and hash it */ + * get() and hash it */ static struct vx_info * __create_vx_info(int id) { @@ -331,9 +328,8 @@ static struct vx_info * __create_vx_info vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id); - if (!(new = __alloc_vx_info(id))) { + if (!(new = __alloc_vx_info(id))) return ERR_PTR(-ENOMEM); - } /* required to make dynamic xids unique */ spin_lock(&vx_info_hash_lock); @@ -348,7 +344,7 @@ static struct vx_info * __create_vx_info } new->vx_id = id; } - /* existing context requested */ + /* static context requested */ else if ((vxi = __lookup_vx_info(id))) { vxdprintk(VXD_CBIT(xid, 0), "create_vx_info(%d) = %p (already there)", id, vxi); @@ -366,7 +362,7 @@ static struct vx_info * __create_vx_info goto out_unlock; } - /* new context requested */ + /* new context */ vxdprintk(VXD_CBIT(xid, 0), "create_vx_info(%d) = %p (new)", id, new); __hash_vx_info(get_vx_info(new)); @@ -470,6 +466,7 @@ out: } #endif + int vx_migrate_user(struct task_struct *p, struct vx_info *vxi) { struct user_struct *new_user, *old_user; diff -NurpP --minimal linux-2.6.11.10-vs2.0/kernel/vserver/network.c linux-2.6.11.10-vs2.0-p1/kernel/vserver/network.c --- linux-2.6.11.10-vs2.0/kernel/vserver/network.c 2005-05-21 04:29:23 +0200 +++ linux-2.6.11.10-vs2.0-p1/kernel/vserver/network.c 2005-05-22 14:58:04 +0200 @@ -9,6 +9,7 @@ * V0.02 cleaned up implementation * V0.03 added equiv nx commands * V0.04 switch to RCU based hash + * V0.05 and back to locking again * */ @@ -39,7 +40,7 @@ static struct nx_info *__alloc_nx_info(n memset (new, 0, sizeof(struct nx_info)); new->nx_id = nid; - INIT_RCU_HEAD(&new->nx_rcu); + // INIT_RCU_HEAD(&new->nx_rcu); INIT_HLIST_NODE(&new->nx_hlist); atomic_set(&new->nx_refcnt, 0); atomic_set(&new->nx_usecnt, 0); @@ -47,7 +48,7 @@ static struct nx_info *__alloc_nx_info(n /* rest of init goes here */ vxdprintk(VXD_CBIT(nid, 0), - "alloc_nx_info() = %p", new); + "alloc_nx_info(%d) = %p", nid, new); return new; } @@ -354,6 +355,7 @@ out: /* * migrate task to new network + * gets nxi, puts old_nxi on change */ int nx_migrate_task(struct task_struct *p, struct nx_info *nxi) @@ -537,10 +539,10 @@ int vc_net_create(uint32_t nid, void __u if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if ((nid >= MIN_D_CONTEXT) && (nid != VX_DYNAMIC_ID)) + if ((nid > MAX_S_CONTEXT) && (nid != VX_DYNAMIC_ID)) return -EINVAL; - if (nid < 1) + if (nid < 2) return -EINVAL; new_nxi = __loc_nx_info(nid, &ret);