Merge "soc: qcom: hab: move linux-specific implementation of hab_ctx_free out side of the common file"
This commit is contained in:
commit
da2ba4489a
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user