/* AH objects are unique in that the create_ah verb *canbecalledinatomiccontext.Ifthecreate_ah *callisnotsleepableuseGFP_ATOMIC.
*/
gfp_flags = sleepable ? GFP_KERNEL : GFP_ATOMIC;
if (sleepable)
might_sleep();
err = xa_alloc_cyclic(&pool->xa, &elem->index, NULL, pool->limit,
&pool->next, gfp_flags); if (err < 0) goto err_cnt;
/* erase xarray entry to prevent looking up *thepoolelemfromitsindex
*/
xa_ret = xa_erase(xa, elem->index);
WARN_ON(xa_err(xa_ret));
/* if this is the last call to rxe_put complete the *object.Itissafetotouchobj->elemafterthissince *itisfreedbelow
*/
__rxe_put(elem);
/* wait until all references to the object have been *droppedbeforefinalobjectspecificcleanupand *returntordma-core
*/ if (sleepable) { if (!completion_done(&elem->complete)) {
ret = wait_for_completion_timeout(&elem->complete,
msecs_to_jiffies(50000));
/* Shouldn't happen. There are still references to *theobjectbut,ratherthandeadlock,freethe *objectorpassbacktordma-core.
*/ if (WARN_ON(!ret))
err = -ETIMEDOUT;
}
} else { unsignedlong until = jiffies + RXE_POOL_TIMEOUT;
/* AH objects are unique in that the destroy_ah verb *canbecalledinatomiccontext.Thisdelay *replacesthewait_for_completioncallabove *whenthedestroy_ahcallisnotsleepable
*/ while (!completion_done(&elem->complete) &&
time_before(jiffies, until))
mdelay(1);
if (WARN_ON(!completion_done(&elem->complete)))
err = -ETIMEDOUT;
}
if (pool->cleanup)
pool->cleanup(elem);
atomic_dec(&pool->num_elem);
return err;
}
int __rxe_get(struct rxe_pool_elem *elem)
{ return kref_get_unless_zero(&elem->ref_cnt);
}
int __rxe_put(struct rxe_pool_elem *elem)
{ return kref_put(&elem->ref_cnt, rxe_elem_release);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.