aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/cxl/file.c
diff options
context:
space:
mode:
authorVaibhav Jain <vaibhav@linux.vnet.ibm.com>2015-11-15 23:03:45 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2015-11-23 22:21:27 -0500
commit1b5df59e50874b9034c0fa389cd52b65f1f93292 (patch)
treeda67ac4132e264c0fda8dd268fbeb2fa37676771 /drivers/misc/cxl/file.c
parent1ec218373b8ebda821aec00bb156a9c94fad9cd4 (diff)
cxl: Fix possible idr warning when contexts are released
An idr warning is reported when a context is release after the capi card is unbound from the cxl driver via sysfs. Below are the steps to reproduce: 1. Create multiple afu contexts in an user-space application using libcxl. 2. Unbind capi card from cxl using command of form echo <capi-card-pci-addr> > /sys/bus/pci/drivers/cxl-pci/unbind 3. Exit/kill the application owning afu contexts. After above steps a warning message is usually seen in the kernel logs of the form "idr_remove called for id=<context-id> which is not allocated." This is caused by the function cxl_release_afu which destroys the contexts_idr table. So when a context is release no entry for context pe is found in the contexts_idr table and idr code prints this warning. This patch fixes this issue by increasing & decreasing the ref-count on the afu device when a context is initialized or when its freed respectively. This prevents the afu from being released until all the afu contexts have been released. The patch introduces two new functions namely cxl_afu_get/put that manage the ref-count on the afu device. Also the patch removes code inside cxl_dev_context_init that increases ref on the afu device as its guaranteed to be alive during this function. Reported-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com> Acked-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'drivers/misc/cxl/file.c')
-rw-r--r--drivers/misc/cxl/file.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 7ccd2998be92..5cc14599837d 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -67,7 +67,13 @@ static int __afu_open(struct inode *inode, struct file *file, bool master)
67 spin_unlock(&adapter->afu_list_lock); 67 spin_unlock(&adapter->afu_list_lock);
68 goto err_put_adapter; 68 goto err_put_adapter;
69 } 69 }
70 get_device(&afu->dev); 70
71 /*
72 * taking a ref to the afu so that it doesn't go away
73 * for rest of the function. This ref is released before
74 * we return.
75 */
76 cxl_afu_get(afu);
71 spin_unlock(&adapter->afu_list_lock); 77 spin_unlock(&adapter->afu_list_lock);
72 78
73 if (!afu->current_mode) 79 if (!afu->current_mode)
@@ -90,13 +96,12 @@ static int __afu_open(struct inode *inode, struct file *file, bool master)
90 file->private_data = ctx; 96 file->private_data = ctx;
91 cxl_ctx_get(); 97 cxl_ctx_get();
92 98
93 /* Our ref on the AFU will now hold the adapter */ 99 /* indicate success */
94 put_device(&adapter->dev); 100 rc = 0;
95
96 return 0;
97 101
98err_put_afu: 102err_put_afu:
99 put_device(&afu->dev); 103 /* release the ref taken earlier */
104 cxl_afu_put(afu);
100err_put_adapter: 105err_put_adapter:
101 put_device(&adapter->dev); 106 put_device(&adapter->dev);
102 return rc; 107 return rc;
@@ -131,8 +136,6 @@ int afu_release(struct inode *inode, struct file *file)
131 mutex_unlock(&ctx->mapping_lock); 136 mutex_unlock(&ctx->mapping_lock);
132 } 137 }
133 138
134 put_device(&ctx->afu->dev);
135
136 /* 139 /*
137 * At this this point all bottom halfs have finished and we should be 140 * At this this point all bottom halfs have finished and we should be
138 * getting no more IRQs from the hardware for this context. Once it's 141 * getting no more IRQs from the hardware for this context. Once it's