+ __dealloc_vx_info(new);
+ return vxi;
+}
+
+
+
+/* exported stuff */
+
+
+
+void rcu_free_vx_info(void *obj)
+{
+ struct vx_info *vxi = obj;
+ int usecnt, refcnt;
+
+ usecnt = atomic_read(&vxi->vx_usecnt);
+ BUG_ON(usecnt < 0);
+
+ refcnt = atomic_read(&vxi->vx_refcnt);
+ BUG_ON(refcnt < 0);
+
+ if (!usecnt)
+ __dealloc_vx_info(vxi);
+ else
+ printk("!!! rcu didn't free\n");
+}
+
+void unhash_vx_info(struct vx_info *vxi)
+{
+ spin_lock(&vx_info_hash_lock);
+ __unhash_vx_info(vxi);
+ spin_unlock(&vx_info_hash_lock);
+}
+
+/* locate_vx_info()
+
+ * search for a vx_info and get() it
+ * negative id means current */
+
+struct vx_info *locate_vx_info(int id)
+{
+ struct vx_info *vxi;
+
+ if (id < 0) {
+ vxi = get_vx_info(current->vx_info);
+ } else {
+ rcu_read_lock();
+ vxi = get_vx_info(__lookup_vx_info(id));
+ rcu_read_unlock();
+ }