Merge "soc: qcom: hab: move linux-specific implementation of hab_ctx_free out side of the common file"

This commit is contained in:
qctecmdr 2024-01-10 12:47:40 -08:00 committed by Gerrit - the friendly Code Review server
commit da2ba4489a
3 changed files with 39 additions and 32 deletions

View File

@ -122,7 +122,7 @@ struct uhab_context *hab_ctx_alloc(int kernel)
* ->habmem_export_destroy->habmem_exp_release,
* where dma_buf_unmap_attachment() & dma_buf_detach() might sleep.
*/
static void hab_ctx_free_fn(struct uhab_context *ctx)
void hab_ctx_free_fn(struct uhab_context *ctx)
{
struct hab_export_ack_recvd *exp_ack_recvd, *expack_tmp;
struct hab_import_ack_recvd *imp_ack_recvd, *impack_tmp;
@ -272,39 +272,9 @@ static void hab_ctx_free_fn(struct uhab_context *ctx)
kfree(ctx);
}
static void hab_ctx_free_work_fn(struct work_struct *work)
{
struct uhab_context *ctx =
container_of(work, struct uhab_context, destroy_work);
hab_ctx_free_fn(ctx);
}
/*
* ctx can only be freed after all the vchan releases the refcnt
* and hab_release() is called.
*
* this function might be called in atomic context in following situations
* (only applicable to Linux):
* 1. physical_channel_rx_dispatch()->hab_msg_recv()->hab_vchan_put()
* ->hab_ctx_put()->hab_ctx_free() in tasklet.
* 2. hab client holds spin_lock and calls hab_vchan_close()->hab_vchan_put()
* ->hab_vchan_free()->hab_ctx_free().
*/
void hab_ctx_free(struct kref *ref)
{
struct uhab_context *ctx =
container_of(ref, struct uhab_context, refcount);
if (likely(preemptible())) {
hab_ctx_free_fn(ctx);
} else {
pr_info("In non-preemptive context now, ctx owner %d\n",
ctx->owner);
INIT_WORK(&ctx->destroy_work, hab_ctx_free_work_fn);
schedule_work(&ctx->destroy_work);
}
hab_ctx_free_os(ref);
}
/*

View File

@ -629,6 +629,9 @@ struct uhab_context *hab_ctx_alloc(int kernel);
void hab_ctx_free(struct kref *ref);
void hab_ctx_free_fn(struct uhab_context *ctx);
void hab_ctx_free_os(struct kref *ref);
static inline void hab_ctx_get(struct uhab_context *ctx)
{
if (ctx)

View File

@ -11,6 +11,40 @@ unsigned int get_refcnt(struct kref ref)
return kref_read(&ref);
}
static void hab_ctx_free_work_fn(struct work_struct *work)
{
struct uhab_context *ctx =
container_of(work, struct uhab_context, destroy_work);
hab_ctx_free_fn(ctx);
}
/*
* ctx can only be freed after all the vchan releases the refcnt
* and hab_release() is called.
*
* this function might be called in atomic context in following situations
* (only applicable to Linux):
* 1. physical_channel_rx_dispatch()->hab_msg_recv()->hab_vchan_put()
* ->hab_ctx_put()->hab_ctx_free() in tasklet.
* 2. hab client holds spin_lock and calls hab_vchan_close()->hab_vchan_put()
* ->hab_vchan_free()->hab_ctx_free().
*/
void hab_ctx_free_os(struct kref *ref)
{
struct uhab_context *ctx =
container_of(ref, struct uhab_context, refcount);
if (likely(preemptible())) {
hab_ctx_free_fn(ctx);
} else {
pr_info("In non-preemptive context now, ctx owner %d\n",
ctx->owner);
INIT_WORK(&ctx->destroy_work, hab_ctx_free_work_fn);
schedule_work(&ctx->destroy_work);
}
}
static int hab_open(struct inode *inodep, struct file *filep)
{
int result = 0;