提交 3f8dc44d 编写于 作者: M Michael Neuling 提交者: Michael Ellerman

cxl: Fix refcounting in kernel API

Currently the kernel API AFU dev refcounting is done on context start and stop.
This patch moves this refcounting to context init and release, bringing it
inline with how the userspace API does it.

Without this we've seen the refcounting on the AFU get out of whack between the
user and kernel API usage.  This causes the AFU structures to be freed when
they are actually still in use.

This fixes some kref warnings we've been seeing and spurious ErrIVTE IRQs.
Signed-off-by: NMichael Neuling <mikey@neuling.org>
Acked-by: NIan Munsie <imunsie@au1.ibm.com>
Signed-off-by: NMichael Ellerman <mpe@ellerman.id.au>
上级 b32aadc1
...@@ -23,6 +23,7 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev) ...@@ -23,6 +23,7 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
afu = cxl_pci_to_afu(dev); afu = cxl_pci_to_afu(dev);
get_device(&afu->dev);
ctx = cxl_context_alloc(); ctx = cxl_context_alloc();
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return ctx; return ctx;
...@@ -31,6 +32,7 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev) ...@@ -31,6 +32,7 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
rc = cxl_context_init(ctx, afu, false, NULL); rc = cxl_context_init(ctx, afu, false, NULL);
if (rc) { if (rc) {
kfree(ctx); kfree(ctx);
put_device(&afu->dev);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
cxl_assign_psn_space(ctx); cxl_assign_psn_space(ctx);
...@@ -60,6 +62,8 @@ int cxl_release_context(struct cxl_context *ctx) ...@@ -60,6 +62,8 @@ int cxl_release_context(struct cxl_context *ctx)
if (ctx->status != CLOSED) if (ctx->status != CLOSED)
return -EBUSY; return -EBUSY;
put_device(&ctx->afu->dev);
cxl_context_free(ctx); cxl_context_free(ctx);
return 0; return 0;
...@@ -159,7 +163,6 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, ...@@ -159,7 +163,6 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
} }
ctx->status = STARTED; ctx->status = STARTED;
get_device(&ctx->afu->dev);
out: out:
mutex_unlock(&ctx->status_mutex); mutex_unlock(&ctx->status_mutex);
return rc; return rc;
...@@ -175,12 +178,7 @@ EXPORT_SYMBOL_GPL(cxl_process_element); ...@@ -175,12 +178,7 @@ EXPORT_SYMBOL_GPL(cxl_process_element);
/* Stop a context. Returns 0 on success, otherwise -Errno */ /* Stop a context. Returns 0 on success, otherwise -Errno */
int cxl_stop_context(struct cxl_context *ctx) int cxl_stop_context(struct cxl_context *ctx)
{ {
int rc; return __detach_context(ctx);
rc = __detach_context(ctx);
if (!rc)
put_device(&ctx->afu->dev);
return rc;
} }
EXPORT_SYMBOL_GPL(cxl_stop_context); EXPORT_SYMBOL_GPL(cxl_stop_context);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册