static void __put_pid(struct pid_kddm_object *obj) { struct pid *pid = obj->pid; int nr = pid_knr(pid); int may_put; int grabbed = 0; /* Try to avoid grabing the kddm object */ read_lock(&tasklist_lock); spin_lock(&pid_kddm_lock); may_put = may_put_pid(obj); spin_unlock(&pid_kddm_lock); if (!may_put) goto release_work; read_unlock(&tasklist_lock); /* The pid seems to be unused locally. Have to check globally. */ /* Prevent pidmaps from changing host nodes. */ pidmap_map_read_lock(); fkddm_grab_object(kddm_def_ns, PID_KDDM_ID, nr, KDDM_NO_FT_REQ | KDDM_DONT_KILL); grabbed = 1; read_lock(&tasklist_lock); spin_lock(&pid_kddm_lock); may_put = may_put_pid(obj); if (may_put) { obj->active = 0; obj->node_count--; if (obj->node_count) /* Still used elsewhere */ may_put = 0; } spin_unlock(&pid_kddm_lock); release_work: spin_lock(&put_pid_wq_lock); list_del_init(&obj->wq); spin_unlock(&put_pid_wq_lock); read_unlock(&tasklist_lock); if (may_put) { _kddm_remove_frozen_object(pid_kddm_set, nr); pidmap_map_read_unlock(); } else if (grabbed) { _kddm_put_object(pid_kddm_set, nr); pidmap_map_read_unlock(); } }
void krg_ipc_shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) { struct kddm_set *mm_set; int index; key_t key; index = ipcid_to_idx(shp->shm_perm.id); key = shp->shm_perm.key; mm_set = shp->shm_file->f_dentry->d_inode->i_mapping->kddm_set; if (key != IPC_PRIVATE) { _kddm_grab_object_no_ft(shm_ids(ns).krgops->key_kddm_set, key); _kddm_remove_frozen_object(shm_ids(ns).krgops->key_kddm_set, key); } local_shm_unlock(shp); _kddm_remove_frozen_object(shm_ids(ns).krgops->data_kddm_set, index); _destroy_kddm_set(mm_set); krg_ipc_rmid(&shm_ids(ns), index); }
void krg_task_abort(struct task_struct *task) { struct task_kddm_object *obj = task->task_obj; #ifdef CONFIG_KRG_EPM if (krg_current) return; #endif if (!obj) return; obj->write_locked = 2; up_write(&obj->sem); _kddm_remove_frozen_object(task_kddm_set, obj->pid); }