Esempio n. 1
0
/*
 * Release all access permits and detach all associated attaches for the given
 * thread group.
 */
void
xpmem_release_aps_of_tg(struct xpmem_thread_group *ap_tg)
{
    struct xpmem_hashlist *hashlist;
    struct xpmem_access_permit *ap;
    int index;

    for (index = 0; index < XPMEM_AP_HASHTABLE_SIZE; index++) {
        hashlist = &ap_tg->ap_hashtable[index];

        read_lock(&hashlist->lock);
        while (!list_empty(&hashlist->list)) {
            ap = list_entry((&hashlist->list)->next,
                    struct xpmem_access_permit,
                    ap_hashnode);
            xpmem_ap_ref(ap);
            read_unlock(&hashlist->lock);

            xpmem_release_ap(ap_tg, ap);

            xpmem_ap_deref(ap);
            read_lock(&hashlist->lock);
        }
        read_unlock(&hashlist->lock);
    }
}
Esempio n. 2
0
/*
 * Detach an attached XPMEM address segment.
 */
int
xpmem_detach(vaddr_t at_vaddr)
{
    struct xpmem_thread_group *tg;
    struct xpmem_access_permit *ap;
    struct xpmem_attachment *att;

    tg = xpmem_tg_ref_by_gid(current->aspace->id);
    if (IS_ERR(tg))
	return PTR_ERR(tg);

    att = xpmem_att_ref_by_vaddr(tg, at_vaddr);
    if (IS_ERR(att)) {
	xpmem_tg_deref(tg);
	return PTR_ERR(att);
    }

    mutex_lock(&att->mutex);

    if (att->flags & XPMEM_FLAG_DESTROYING) {
	mutex_unlock(&att->mutex);
	xpmem_att_deref(att);
	xpmem_tg_deref(tg);
	return 0;
    }
    att->flags |= XPMEM_FLAG_DESTROYING;

    ap = att->ap;
    xpmem_ap_ref(ap);

    if (current->aspace->id != ap->tg->gid) {
	att->flags &= ~XPMEM_FLAG_DESTROYING;
        xpmem_ap_deref(ap);
        mutex_unlock(&att->mutex);
        xpmem_att_deref(att);
        return -EACCES;
    }

    __xpmem_detach_att(ap, att);

    mutex_unlock(&att->mutex);

    xpmem_att_destroyable(att);

    xpmem_ap_deref(ap);
    xpmem_att_deref(att);
    xpmem_tg_deref(tg);

    return 0;
}