*
* Virtual Server: Context Support
*
- * Copyright (C) 2003-2005 Herbert Pötzl
+ * Copyright (C) 2003-2004 Herbert Pötzl
*
* V0.01 context helper
* V0.02 vx_ctx_kill syscall command
* V0.06 task_xid and info commands
* V0.07 context flags and caps
* V0.08 switch to RCU based hash
- * V0.09 revert to non RCU for now
- * V0.10 and back to working RCU hash
*
*/
#include <linux/config.h>
#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/namespace.h>
-
-#include <linux/sched.h>
-#include <linux/vserver/network.h>
+#include <linux/vserver.h>
#include <linux/vserver/legacy.h>
-#include <linux/vserver/limit.h>
-#include <linux/vserver/debug.h>
+#include <linux/vs_base.h>
#include <linux/vs_context.h>
-#include <linux/vserver/context_cmd.h>
-#include <linux/ckrm_events.h> /* needed for ckrm_cb_xid() */
+#include <linux/kernel_stat.h>
+#include <linux/namespace.h>
+#include <linux/rcupdate.h>
-#include <asm/errno.h>
+#define CKRM_VSERVER_INTEGRATION
+#ifdef CKRM_VSERVER_INTEGRATION
+#include <linux/ckrm.h>
+#endif //CKRM_VSERVER_INTEGRATION
-#include "cvirt_init.h"
-#include "limit_init.h"
-#include "sched_init.h"
+#include <asm/errno.h>
/* __alloc_vx_info()
vxdprintk(VXD_CBIT(xid, 0),
"alloc_vx_info(%d) = %p", xid, new);
- vxh_alloc_vx_info(new);
return new;
}
{
vxdprintk(VXD_CBIT(xid, 0),
"dealloc_vx_info(%p)", vxi);
- vxh_dealloc_vx_info(vxi);
vxi->vx_hlist.next = LIST_POISON1;
vxi->vx_id = -1;
return usecnt;
}
-static void __rcu_put_vx_info(struct rcu_head *head)
+#if 0
+
+static void __rcu_free_vx_info(struct rcu_head *head)
{
struct vx_info *vxi = container_of(head, struct vx_info, vx_rcu);
+ BUG_ON(!head);
vxdprintk(VXD_CBIT(xid, 3),
- "__rcu_put_vx_info(%p[#%d]): %d,%d",
- vxi, vxi->vx_id,
- atomic_read(&vxi->vx_usecnt),
- atomic_read(&vxi->vx_refcnt));
- put_vx_info(vxi);
+ "rcu_free_vx_info(%p): uc=%d", vxi,
+ atomic_read(&vxi->vx_usecnt));
+
+ __free_vx_info(vxi);
}
-void __shutdown_vx_info(struct vx_info *vxi)
+#endif
+
+void free_vx_info(struct vx_info *vxi)
{
struct namespace *namespace;
struct fs_struct *fs;
- might_sleep();
+ /* context shutdown is mandatory */
+ // BUG_ON(vxi->vx_state != VXS_SHUTDOWN);
namespace = xchg(&vxi->vx_namespace, NULL);
+ fs = xchg(&vxi->vx_fs, NULL);
+
if (namespace)
put_namespace(namespace);
-
- fs = xchg(&vxi->vx_fs, NULL);
if (fs)
put_fs_struct(fs);
-}
-
-/* exported stuff */
-
-void free_vx_info(struct vx_info *vxi)
-{
- /* context shutdown is mandatory */
- // BUG_ON(vxi->vx_state != VXS_SHUTDOWN);
-
- BUG_ON(vxi->vx_state & VXS_HASHED);
-
- BUG_ON(vxi->vx_namespace);
- BUG_ON(vxi->vx_fs);
BUG_ON(__free_vx_info(vxi));
+ // call_rcu(&i->vx_rcu, __rcu_free_vx_info);
}
vxdprintk(VXD_CBIT(xid, 4),
"__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
- vxh_hash_vx_info(vxi);
-
get_vx_info(vxi);
vxi->vx_state |= VXS_HASHED;
head = &vx_info_hash[__hashval(vxi->vx_id)];
{
vxdprintk(VXD_CBIT(xid, 4),
"__unhash_vx_info: %p[#%d]", vxi, vxi->vx_id);
- vxh_unhash_vx_info(vxi);
-
vxi->vx_state &= ~VXS_HASHED;
hlist_del_rcu(&vxi->vx_hlist);
-
- call_rcu(&vxi->vx_rcu, __rcu_put_vx_info);
+ put_vx_info(vxi);
}
{
struct hlist_head *head = &vx_info_hash[__hashval(xid)];
struct hlist_node *pos;
- struct vx_info *vxi;
hlist_for_each_rcu(pos, head) {
- vxi = hlist_entry(pos, struct vx_info, vx_hlist);
+ struct vx_info *vxi =
+ hlist_entry(pos, struct vx_info, vx_hlist);
if ((vxi->vx_id == xid) &&
vx_info_state(vxi, VXS_HASHED))
- goto found;
+ return vxi;
}
- vxi = NULL;
-found:
- vxdprintk(VXD_CBIT(xid, 0),
- "__lookup_vx_info(#%u): %p[#%u]",
- xid, vxi, vxi?vxi->vx_id:0);
- vxh_lookup_vx_info(xid, vxi);
- return vxi;
+ return NULL;
}
/* __vx_dynamic_id()
* find unused dynamic xid
- * requires the rcu_read_lock()
* requires the hash_lock to be held */
static inline xid_t __vx_dynamic_id(void)
return NULL;
}
- /* FIXME is this required at all ? */
- rcu_read_lock();
- /* required to make dynamic xids unique */
spin_lock(&vx_info_hash_lock);
/* dynamic context requested */
out_unlock:
spin_unlock(&vx_info_hash_lock);
- rcu_read_unlock();
- vxh_loc_vx_info(id, vxi);
if (new)
__dealloc_vx_info(new);
return vxi;
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);
out:
- ckrm_cb_xid(p);
+#ifdef CKRM_VSERVER_INTEGRATION
+ do {
+ ckrm_cb_xid(p);
+ } while (0);
+#endif //CKRM_VSERVER_INTEGRATION
+
put_vx_info(old_vxi);
return ret;
read_unlock(&tasklist_lock);
}
else
- xid = vx_current_xid();
+ xid = current->xid;
return xid;
}
#include <linux/module.h>
+// EXPORT_SYMBOL_GPL(rcu_free_vx_info);
EXPORT_SYMBOL_GPL(free_vx_info);
+EXPORT_SYMBOL_GPL(vx_info_hash_lock);
EXPORT_SYMBOL_GPL(unhash_vx_info);