Instead of creating the context when the user opens the device, create the context when the first IOCTL that needs a context is called.
This change is required to provide backward compatibility for older user-space when the driver will require the user to create a context. Signed-off-by: Oded Gabbay <[email protected]> --- drivers/misc/habanalabs/context.c | 29 +++++++++++++++++++++++- drivers/misc/habanalabs/device.c | 5 +++- drivers/misc/habanalabs/habanalabs.h | 2 ++ drivers/misc/habanalabs/habanalabs_drv.c | 13 ----------- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/drivers/misc/habanalabs/context.c b/drivers/misc/habanalabs/context.c index 771a1055e67b..3c1f7c29e908 100644 --- a/drivers/misc/habanalabs/context.c +++ b/drivers/misc/habanalabs/context.c @@ -198,7 +198,34 @@ struct dma_fence *hl_ctx_get_fence(struct hl_ctx *ctx, u64 seq) bool hl_ctx_is_valid(struct hl_fpriv *hpriv) { - return hpriv->ctx ? true : false; + struct hl_device *hdev = hpriv->hdev; + bool valid = true; + int rc; + + /* First thing, to minimize latency impact, check if context exists. + * If so, exit immediately + */ + if (hpriv->ctx) + return true; + + mutex_lock(&hdev->lazy_ctx_creation_lock); + + /* We must check again the existence of the context. This is because + * there could be competing threads in the same process that call + * IOCTLs at the same time. In this case, we must protect against double + * creation of a context + */ + if (!hpriv->ctx) { + rc = hl_ctx_create(hdev, hpriv); + if (rc) { + dev_err(hdev->dev, "Failed to create context %d\n", rc); + valid = false; + } + } + + mutex_unlock(&hdev->lazy_ctx_creation_lock); + + return valid; } /* diff --git a/drivers/misc/habanalabs/device.c b/drivers/misc/habanalabs/device.c index 0c4894dd9c02..b63beb73ec76 100644 --- a/drivers/misc/habanalabs/device.c +++ b/drivers/misc/habanalabs/device.c @@ -58,8 +58,9 @@ static void hpriv_release(struct kref *ref) /* Now the FD is really closed */ atomic_dec(&hdev->fd_open_cnt); - /* This allows a new user context to open the device */ + mutex_lock(&hdev->lazy_ctx_creation_lock); hdev->user_ctx = NULL; + mutex_unlock(&hdev->lazy_ctx_creation_lock); } void hl_hpriv_get(struct hl_fpriv *hpriv) @@ -233,6 +234,7 @@ static int device_early_init(struct hl_device *hdev) mutex_init(&hdev->send_cpu_message_lock); mutex_init(&hdev->debug_lock); mutex_init(&hdev->mmu_cache_lock); + mutex_init(&hdev->lazy_ctx_creation_lock); INIT_LIST_HEAD(&hdev->hw_queues_mirror_list); spin_lock_init(&hdev->hw_queues_mirror_lock); atomic_set(&hdev->in_reset, 0); @@ -262,6 +264,7 @@ static int device_early_init(struct hl_device *hdev) */ static void device_early_fini(struct hl_device *hdev) { + mutex_destroy(&hdev->lazy_ctx_creation_lock); mutex_destroy(&hdev->mmu_cache_lock); mutex_destroy(&hdev->debug_lock); mutex_destroy(&hdev->send_cpu_message_lock); diff --git a/drivers/misc/habanalabs/habanalabs.h b/drivers/misc/habanalabs/habanalabs.h index 475cdaa0005e..d0e55839d673 100644 --- a/drivers/misc/habanalabs/habanalabs.h +++ b/drivers/misc/habanalabs/habanalabs.h @@ -1183,6 +1183,7 @@ struct hl_device_reset_work { * @cb_pool: list of preallocated CBs. * @cb_pool_lock: protects the CB pool. * @user_ctx: current user context executing. + * @lazy_ctx_creation_lock: lock to protect lazy creation of context * @dram_used_mem: current DRAM memory consumption. * @timeout_jiffies: device CS timeout value. * @max_power: the max power of the device, as configured by the sysadmin. This @@ -1261,6 +1262,7 @@ struct hl_device { /* TODO: remove user_ctx for multiple process support */ struct hl_ctx *user_ctx; + struct mutex lazy_ctx_creation_lock; atomic64_t dram_used_mem; u64 timeout_jiffies; diff --git a/drivers/misc/habanalabs/habanalabs_drv.c b/drivers/misc/habanalabs/habanalabs_drv.c index 678f61646ca9..b2c52e46e130 100644 --- a/drivers/misc/habanalabs/habanalabs_drv.c +++ b/drivers/misc/habanalabs/habanalabs_drv.c @@ -141,12 +141,6 @@ int hl_device_open(struct inode *inode, struct file *filp) hl_cb_mgr_init(&hpriv->cb_mgr); hl_ctx_mgr_init(&hpriv->ctx_mgr); - rc = hl_ctx_create(hdev, hpriv); - if (rc) { - dev_err(hdev->dev, "Failed to open FD (CTX fail)\n"); - goto out_err; - } - hpriv->taskpid = find_get_pid(current->pid); /* @@ -160,13 +154,6 @@ int hl_device_open(struct inode *inode, struct file *filp) return 0; -out_err: - filp->private_data = NULL; - hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr); - hl_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr); - mutex_destroy(&hpriv->restore_phase_mutex); - kfree(hpriv); - close_device: atomic_dec(&hdev->fd_open_cnt); return rc; -- 2.17.1

