Commit e2a079a2 authored by Tomer Tayar's avatar Tomer Tayar Committed by Oded Gabbay

habanalabs: verify that kernel CB is destroyed only once

Remove the distinction between user CB and kernel CB, and verify for
both that they are not destroyed more than once.

As kernel CB might be taken from the pre-allocated CB pool, so we need
to clear the handle destroyed indication when returning a CB to the
pool.
Signed-off-by: default avatarTomer Tayar <ttayar@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent 20faaeec
...@@ -88,6 +88,7 @@ static void cb_fini(struct hl_device *hdev, struct hl_cb *cb) ...@@ -88,6 +88,7 @@ static void cb_fini(struct hl_device *hdev, struct hl_cb *cb)
static void cb_do_release(struct hl_device *hdev, struct hl_cb *cb) static void cb_do_release(struct hl_device *hdev, struct hl_cb *cb)
{ {
if (cb->is_pool) { if (cb->is_pool) {
atomic_set(&cb->is_handle_destroyed, 0);
spin_lock(&hdev->cb_pool_lock); spin_lock(&hdev->cb_pool_lock);
list_add(&cb->pool_list, &hdev->cb_pool); list_add(&cb->pool_list, &hdev->cb_pool);
spin_unlock(&hdev->cb_pool_lock); spin_unlock(&hdev->cb_pool_lock);
...@@ -301,28 +302,23 @@ int hl_cb_destroy(struct hl_mem_mgr *mmg, u64 cb_handle) ...@@ -301,28 +302,23 @@ int hl_cb_destroy(struct hl_mem_mgr *mmg, u64 cb_handle)
struct hl_cb *cb; struct hl_cb *cb;
int rc; int rc;
/* Make sure that a CB handle isn't destroyed by user more than once */
if (!mmg->is_kernel_mem_mgr) {
cb = hl_cb_get(mmg, cb_handle); cb = hl_cb_get(mmg, cb_handle);
if (!cb) { if (!cb) {
dev_dbg(mmg->dev, "CB destroy failed, no CB was found for handle %#llx\n", dev_dbg(mmg->dev, "CB destroy failed, no CB was found for handle %#llx\n",
cb_handle); cb_handle);
rc = -EINVAL; return -EINVAL;
goto out;
} }
/* Make sure that CB handle isn't destroyed more than once */
rc = atomic_cmpxchg(&cb->is_handle_destroyed, 0, 1); rc = atomic_cmpxchg(&cb->is_handle_destroyed, 0, 1);
hl_cb_put(cb); hl_cb_put(cb);
if (rc) { if (rc) {
dev_dbg(mmg->dev, "CB destroy failed, handle %#llx was already destroyed\n", dev_dbg(mmg->dev, "CB destroy failed, handle %#llx was already destroyed\n",
cb_handle); cb_handle);
rc = -EINVAL; return -EINVAL;
goto out;
}
} }
rc = hl_mmap_mem_buf_put_handle(mmg, cb_handle); rc = hl_mmap_mem_buf_put_handle(mmg, cb_handle);
out:
if (rc < 0) if (rc < 0)
return rc; /* Invalid handle */ return rc; /* Invalid handle */
......
...@@ -855,7 +855,7 @@ static int device_early_init(struct hl_device *hdev) ...@@ -855,7 +855,7 @@ static int device_early_init(struct hl_device *hdev)
if (rc) if (rc)
goto free_chip_info; goto free_chip_info;
hl_mem_mgr_init(hdev->dev, &hdev->kernel_mem_mgr, 1); hl_mem_mgr_init(hdev->dev, &hdev->kernel_mem_mgr);
hdev->reset_wq = create_singlethread_workqueue("hl_device_reset"); hdev->reset_wq = create_singlethread_workqueue("hl_device_reset");
if (!hdev->reset_wq) { if (!hdev->reset_wq) {
......
...@@ -876,13 +876,11 @@ struct hl_mmap_mem_buf; ...@@ -876,13 +876,11 @@ struct hl_mmap_mem_buf;
* @dev: back pointer to the owning device * @dev: back pointer to the owning device
* @lock: protects handles * @lock: protects handles
* @handles: an idr holding all active handles to the memory buffers in the system. * @handles: an idr holding all active handles to the memory buffers in the system.
* @is_kernel_mem_mgr: indicate whether the memory manager is the per-device kernel memory manager
*/ */
struct hl_mem_mgr { struct hl_mem_mgr {
struct device *dev; struct device *dev;
spinlock_t lock; spinlock_t lock;
struct idr handles; struct idr handles;
u8 is_kernel_mem_mgr;
}; };
/** /**
...@@ -3824,7 +3822,7 @@ __printf(4, 5) int hl_snprintf_resize(char **buf, size_t *size, size_t *offset, ...@@ -3824,7 +3822,7 @@ __printf(4, 5) int hl_snprintf_resize(char **buf, size_t *size, size_t *offset,
char *hl_format_as_binary(char *buf, size_t buf_len, u32 n); char *hl_format_as_binary(char *buf, size_t buf_len, u32 n);
const char *hl_sync_engine_to_string(enum hl_sync_engine_type engine_type); const char *hl_sync_engine_to_string(enum hl_sync_engine_type engine_type);
void hl_mem_mgr_init(struct device *dev, struct hl_mem_mgr *mmg, u8 is_kernel_mem_mgr); void hl_mem_mgr_init(struct device *dev, struct hl_mem_mgr *mmg);
void hl_mem_mgr_fini(struct hl_mem_mgr *mmg); void hl_mem_mgr_fini(struct hl_mem_mgr *mmg);
int hl_mem_mgr_mmap(struct hl_mem_mgr *mmg, struct vm_area_struct *vma, int hl_mem_mgr_mmap(struct hl_mem_mgr *mmg, struct vm_area_struct *vma,
void *args); void *args);
......
...@@ -164,7 +164,7 @@ int hl_device_open(struct inode *inode, struct file *filp) ...@@ -164,7 +164,7 @@ int hl_device_open(struct inode *inode, struct file *filp)
nonseekable_open(inode, filp); nonseekable_open(inode, filp);
hl_ctx_mgr_init(&hpriv->ctx_mgr); hl_ctx_mgr_init(&hpriv->ctx_mgr);
hl_mem_mgr_init(hpriv->hdev->dev, &hpriv->mem_mgr, 0); hl_mem_mgr_init(hpriv->hdev->dev, &hpriv->mem_mgr);
hpriv->taskpid = get_task_pid(current, PIDTYPE_PID); hpriv->taskpid = get_task_pid(current, PIDTYPE_PID);
......
...@@ -308,16 +308,14 @@ int hl_mem_mgr_mmap(struct hl_mem_mgr *mmg, struct vm_area_struct *vma, ...@@ -308,16 +308,14 @@ int hl_mem_mgr_mmap(struct hl_mem_mgr *mmg, struct vm_area_struct *vma,
* *
* @dev: owner device pointer * @dev: owner device pointer
* @mmg: structure to initialize * @mmg: structure to initialize
* @is_kernel_mem_mgr: indicate whether the memory manager is the per-device kernel memory manager
* *
* Initialize an instance of unified memory manager * Initialize an instance of unified memory manager
*/ */
void hl_mem_mgr_init(struct device *dev, struct hl_mem_mgr *mmg, u8 is_kernel_mem_mgr) void hl_mem_mgr_init(struct device *dev, struct hl_mem_mgr *mmg)
{ {
mmg->dev = dev; mmg->dev = dev;
spin_lock_init(&mmg->lock); spin_lock_init(&mmg->lock);
idr_init(&mmg->handles); idr_init(&mmg->handles);
mmg->is_kernel_mem_mgr = is_kernel_mem_mgr;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment