summaryrefslogtreecommitdiffstats
path: root/drivers/misc/habanalabs/device.c
diff options
context:
space:
mode:
authorOded Gabbay <oded.gabbay@gmail.com>2019-02-16 00:39:14 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-02-18 09:46:44 +0100
commit0861e41de53044694bfdf2e8f246a0d8fb077e5d (patch)
tree45ff382ab65bbfd6bf719841e1e551aec0071fb5 /drivers/misc/habanalabs/device.c
parent99b9d7b4970cf131fd17a8f4ad4870049bd7a365 (diff)
downloadlinux-0861e41de53044694bfdf2e8f246a0d8fb077e5d.tar.bz2
habanalabs: add context and ASID modules
This patch adds two modules - ASID and context. Each user process that opens a device's file must have at least one context before it is able to "work" with the device. Each context has its own device address-space and contains information about its runtime state (its active command submissions). To have address-space separation between contexts, each context is assigned a unique ASID, which stands for "address-space id". Goya supports up to 1024 ASIDs. Currently, the driver doesn't support multiple contexts. Therefore, the user doesn't need to actively create a context. A "primary context" is created automatically when the user opens the device's file. Reviewed-by: Mike Rapoport <rppt@linux.ibm.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/habanalabs/device.c')
-rw-r--r--drivers/misc/habanalabs/device.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/misc/habanalabs/device.c b/drivers/misc/habanalabs/device.c
index a4feaa784db3..2423588ecf22 100644
--- a/drivers/misc/habanalabs/device.c
+++ b/drivers/misc/habanalabs/device.c
@@ -22,6 +22,12 @@ static void hpriv_release(struct kref *ref)
put_pid(hpriv->taskpid);
kfree(hpriv);
+
+ /* Now the FD is really closed */
+ atomic_dec(&hdev->fd_open_cnt);
+
+ /* This allows a new user context to open the device */
+ hdev->user_ctx = NULL;
}
void hl_hpriv_get(struct hl_fpriv *hpriv)
@@ -46,6 +52,8 @@ static int hl_device_release(struct inode *inode, struct file *filp)
{
struct hl_fpriv *hpriv = filp->private_data;
+ hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
+
filp->private_data = NULL;
hl_hpriv_put(hpriv);
@@ -137,7 +145,20 @@ static int device_early_init(struct hl_device *hdev)
if (rc)
return rc;
+ rc = hl_asid_init(hdev);
+ if (rc)
+ goto early_fini;
+
+ mutex_init(&hdev->fd_open_cnt_lock);
+ atomic_set(&hdev->fd_open_cnt, 0);
+
return 0;
+
+early_fini:
+ if (hdev->asic_funcs->early_fini)
+ hdev->asic_funcs->early_fini(hdev);
+
+ return rc;
}
/*
@@ -149,9 +170,12 @@ static int device_early_init(struct hl_device *hdev)
static void device_early_fini(struct hl_device *hdev)
{
+ hl_asid_fini(hdev);
+
if (hdev->asic_funcs->early_fini)
hdev->asic_funcs->early_fini(hdev);
+ mutex_destroy(&hdev->fd_open_cnt_lock);
}
/*
@@ -245,11 +269,30 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass)
if (rc)
goto early_fini;
+ /* Allocate the kernel context */
+ hdev->kernel_ctx = kzalloc(sizeof(*hdev->kernel_ctx), GFP_KERNEL);
+ if (!hdev->kernel_ctx) {
+ rc = -ENOMEM;
+ goto sw_fini;
+ }
+
+ hdev->user_ctx = NULL;
+
+ rc = hl_ctx_init(hdev, hdev->kernel_ctx, true);
+ if (rc) {
+ dev_err(hdev->dev, "failed to initialize kernel context\n");
+ goto free_ctx;
+ }
+
dev_notice(hdev->dev,
"Successfully added device to habanalabs driver\n");
return 0;
+free_ctx:
+ kfree(hdev->kernel_ctx);
+sw_fini:
+ hdev->asic_funcs->sw_fini(hdev);
early_fini:
device_early_fini(hdev);
release_device:
@@ -282,6 +325,10 @@ void hl_device_fini(struct hl_device *hdev)
/* Mark device as disabled */
hdev->disabled = true;
+ /* Release kernel context */
+ if ((hdev->kernel_ctx) && (hl_ctx_put(hdev->kernel_ctx) != 1))
+ dev_err(hdev->dev, "kernel ctx is still alive\n");
+
/* Call ASIC S/W finalize function */
hdev->asic_funcs->sw_fini(hdev);