X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fvserver%2Fcontext.c;h=c7a7e0505512e86b4c28c6a21b7cc3c3e6c5f9b3;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=c80df75e96d36b5f1d2462f0ba3243b1ac6ca102;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/kernel/vserver/context.c b/kernel/vserver/context.c index c80df75e9..c7a7e0505 100644 --- a/kernel/vserver/context.c +++ b/kernel/vserver/context.c @@ -16,6 +16,7 @@ * V0.09 revert to non RCU for now * V0.10 and back to working RCU hash * V0.11 and back to locking again + * V0.12 have __create claim() the vxi * */ @@ -195,9 +196,9 @@ static inline void __hash_vx_info(struct vx_info *vxi) static inline void __unhash_vx_info(struct vx_info *vxi) { - vxd_assert_lock(&vx_info_hash_lock); vxdprintk(VXD_CBIT(xid, 4), "__unhash_vx_info: %p[#%d]", vxi, vxi->vx_id); + spin_lock(&vx_info_hash_lock); vxh_unhash_vx_info(vxi); /* context must be hashed */ @@ -205,6 +206,7 @@ static inline void __unhash_vx_info(struct vx_info *vxi) vxi->vx_state &= ~VXS_HASHED; hlist_del(&vxi->vx_hlist); + spin_unlock(&vx_info_hash_lock); } @@ -326,7 +328,7 @@ out_unlock: /* __create_vx_info() * create the requested context - * get() and hash it */ + * get(), claim() and hash it */ static struct vx_info * __create_vx_info(int id) { @@ -371,6 +373,7 @@ static struct vx_info * __create_vx_info(int id) /* new context */ vxdprintk(VXD_CBIT(xid, 0), "create_vx_info(%d) = %p (new)", id, new); + claim_vx_info(new, NULL); __hash_vx_info(get_vx_info(new)); vxi = new, new = NULL; @@ -389,9 +392,7 @@ out_unlock: void unhash_vx_info(struct vx_info *vxi) { __shutdown_vx_info(vxi); - spin_lock(&vx_info_hash_lock); __unhash_vx_info(vxi); - spin_unlock(&vx_info_hash_lock); __wakeup_vx_info(vxi); } @@ -636,7 +637,7 @@ void vx_set_persistent(struct vx_info *vxi) "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id); get_vx_info(vxi); - claim_vx_info(vxi, current); + claim_vx_info(vxi, NULL); } void vx_clear_persistent(struct vx_info *vxi) @@ -644,7 +645,7 @@ void vx_clear_persistent(struct vx_info *vxi) vxdprintk(VXD_CBIT(xid, 6), "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id); - release_vx_info(vxi, current); + release_vx_info(vxi, NULL); put_vx_info(vxi); } @@ -668,11 +669,19 @@ void exit_vx_info(struct task_struct *p, int code) vx_nproc_dec(p); vxi->exit_code = code; + release_vx_info(vxi, p); + } +} + +void exit_vx_info_early(struct task_struct *p, int code) +{ + struct vx_info *vxi = p->vx_info; + + if (vxi) { if (vxi->vx_initpid == p->tgid) vx_exit_init(vxi, p, code); if (vxi->vx_reaper == p) vx_set_reaper(vxi, child_reaper); - release_vx_info(vxi, p); } } @@ -754,26 +763,22 @@ int vc_ctx_create(uint32_t xid, void __user *data) /* initial flags */ new_vxi->vx_flags = vc_data.flagword; - /* get a reference for persistent contexts */ - if ((vc_data.flagword & VXF_PERSISTENT)) - vx_set_persistent(new_vxi); - ret = -ENOEXEC; if (vs_state_change(new_vxi, VSC_STARTUP)) - goto out_unhash; + goto out; + ret = vx_migrate_task(current, new_vxi); - if (!ret) { - /* return context id on success */ - ret = new_vxi->vx_id; + if (ret) goto out; - } -out_unhash: - /* prepare for context disposal */ - new_vxi->vx_state |= VXS_SHUTDOWN; + + /* return context id on success */ + ret = new_vxi->vx_id; + + /* get a reference for persistent contexts */ if ((vc_data.flagword & VXF_PERSISTENT)) - vx_clear_persistent(new_vxi); - __unhash_vx_info(new_vxi); + vx_set_persistent(new_vxi); out: + release_vx_info(new_vxi, NULL); put_vx_info(new_vxi); return ret; }