summaryrefslogtreecommitdiffstats
path: root/drivers/misc/habanalabs/habanalabs_drv.c
diff options
context:
space:
mode:
authorOded Gabbay2019-02-15 23:39:14 +0100
committerGreg Kroah-Hartman2019-02-18 09:46:44 +0100
commit0861e41de53044694bfdf2e8f246a0d8fb077e5d (patch)
tree45ff382ab65bbfd6bf719841e1e551aec0071fb5 /drivers/misc/habanalabs/habanalabs_drv.c
parenthabanalabs: add basic Goya support (diff)
downloadkernel-qcow2-linux-0861e41de53044694bfdf2e8f246a0d8fb077e5d.tar.gz
kernel-qcow2-linux-0861e41de53044694bfdf2e8f246a0d8fb077e5d.tar.xz
kernel-qcow2-linux-0861e41de53044694bfdf2e8f246a0d8fb077e5d.zip
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/habanalabs_drv.c')
-rw-r--r--drivers/misc/habanalabs/habanalabs_drv.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/misc/habanalabs/habanalabs_drv.c b/drivers/misc/habanalabs/habanalabs_drv.c
index edf626b2b7b1..6fddd801aca3 100644
--- a/drivers/misc/habanalabs/habanalabs_drv.c
+++ b/drivers/misc/habanalabs/habanalabs_drv.c
@@ -70,6 +70,7 @@ int hl_device_open(struct inode *inode, struct file *filp)
{
struct hl_device *hdev;
struct hl_fpriv *hpriv;
+ int rc;
mutex_lock(&hl_devs_idr_lock);
hdev = idr_find(&hl_devs_idr, iminor(inode));
@@ -81,9 +82,33 @@ int hl_device_open(struct inode *inode, struct file *filp)
return -ENXIO;
}
+ mutex_lock(&hdev->fd_open_cnt_lock);
+
+ if (hdev->disabled) {
+ dev_err_ratelimited(hdev->dev,
+ "Can't open %s because it is disabled\n",
+ dev_name(hdev->dev));
+ mutex_unlock(&hdev->fd_open_cnt_lock);
+ return -EPERM;
+ }
+
+ if (atomic_read(&hdev->fd_open_cnt)) {
+ dev_info_ratelimited(hdev->dev,
+ "Device %s is already attached to application\n",
+ dev_name(hdev->dev));
+ mutex_unlock(&hdev->fd_open_cnt_lock);
+ return -EBUSY;
+ }
+
+ atomic_inc(&hdev->fd_open_cnt);
+
+ mutex_unlock(&hdev->fd_open_cnt_lock);
+
hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv)
- return -ENOMEM;
+ if (!hpriv) {
+ rc = -ENOMEM;
+ goto close_device;
+ }
hpriv->hdev = hdev;
filp->private_data = hpriv;
@@ -91,9 +116,26 @@ int hl_device_open(struct inode *inode, struct file *filp)
kref_init(&hpriv->refcount);
nonseekable_open(inode, filp);
+ 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);
return 0;
+
+out_err:
+ filp->private_data = NULL;
+ hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
+ kfree(hpriv);
+
+close_device:
+ atomic_dec(&hdev->fd_open_cnt);
+ return rc;
}
/*