2020-08-29 14:44:57

by Oded Gabbay

[permalink] [raw]
Subject: [PATCH 1/3] habanalabs: restructure hl_mmap

Arrange the hl_mmap code to be more structured and expandable for the
future. Add better defines that describe our usage of the vm_pgoff.

Note that I shamelessly took the code and defines from the amdkfd driver
(my previous driver).

Signed-off-by: Oded Gabbay <[email protected]>
---
drivers/misc/habanalabs/common/command_buffer.c | 2 +-
drivers/misc/habanalabs/common/device.c | 8 ++++++--
drivers/misc/habanalabs/common/habanalabs.h | 14 +++++++++++++-
3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/habanalabs/common/command_buffer.c b/drivers/misc/habanalabs/common/command_buffer.c
index e4bbe6a8e00f..68dfbafe3354 100644
--- a/drivers/misc/habanalabs/common/command_buffer.c
+++ b/drivers/misc/habanalabs/common/command_buffer.c
@@ -183,7 +183,7 @@ int hl_cb_create(struct hl_device *hdev, struct hl_cb_mgr *mgr,
* idr is 32-bit so we can safely OR it with a mask that is above
* 32 bit
*/
- *handle = cb->id | HL_MMAP_CB_MASK;
+ *handle = cb->id | HL_MMAP_TYPE_CB;
*handle <<= PAGE_SHIFT;

hl_debugfs_add_cb(cb);
diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c
index 6e916cc22a4c..aa7fa9e94651 100644
--- a/drivers/misc/habanalabs/common/device.c
+++ b/drivers/misc/habanalabs/common/device.c
@@ -123,9 +123,13 @@ static int hl_device_release_ctrl(struct inode *inode, struct file *filp)
static int hl_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct hl_fpriv *hpriv = filp->private_data;
+ unsigned long vm_pgoff;

- if ((vma->vm_pgoff & HL_MMAP_CB_MASK) == HL_MMAP_CB_MASK) {
- vma->vm_pgoff ^= HL_MMAP_CB_MASK;
+ vm_pgoff = vma->vm_pgoff;
+ vma->vm_pgoff = HL_MMAP_OFFSET_VALUE_GET(vm_pgoff);
+
+ switch (vm_pgoff & HL_MMAP_TYPE_MASK) {
+ case HL_MMAP_TYPE_CB:
return hl_cb_mmap(hpriv, vma);
}

diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h
index 6912f88a4b01..cdb7a672ed30 100644
--- a/drivers/misc/habanalabs/common/habanalabs.h
+++ b/drivers/misc/habanalabs/common/habanalabs.h
@@ -22,7 +22,19 @@

#define HL_NAME "habanalabs"

-#define HL_MMAP_CB_MASK (0x8000000000000000ull >> PAGE_SHIFT)
+/* Use upper bits of mmap offset to store habana driver specific information.
+ * bits[63:62] - Encode mmap type
+ * bits[45:0] - mmap offset value
+ *
+ * NOTE: struct vm_area_struct.vm_pgoff uses offset in pages. Hence, these
+ * defines are w.r.t to PAGE_SIZE
+ */
+#define HL_MMAP_TYPE_SHIFT (62 - PAGE_SHIFT)
+#define HL_MMAP_TYPE_MASK (0x3ull << HL_MMAP_TYPE_SHIFT)
+#define HL_MMAP_TYPE_CB (0x2ull << HL_MMAP_TYPE_SHIFT)
+
+#define HL_MMAP_OFFSET_VALUE_MASK (0x3FFFFFFFFFFFull >> PAGE_SHIFT)
+#define HL_MMAP_OFFSET_VALUE_GET(off) (off & HL_MMAP_OFFSET_VALUE_MASK)

#define HL_PENDING_RESET_PER_SEC 30

--
2.17.1


2020-08-29 14:44:58

by Oded Gabbay

[permalink] [raw]
Subject: [PATCH 2/3] habanalabs: clear vm_pgoff before doing the mmap

The driver use vm_pgoff to hold the CB idr handle. Before we actually call
the mapping function, we need to clear the handle so there won't be any
garbage left in vm_pgoff.

Signed-off-by: Oded Gabbay <[email protected]>
---
drivers/misc/habanalabs/common/command_buffer.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/misc/habanalabs/common/command_buffer.c b/drivers/misc/habanalabs/common/command_buffer.c
index 68dfbafe3354..6563e4dfe7b6 100644
--- a/drivers/misc/habanalabs/common/command_buffer.c
+++ b/drivers/misc/habanalabs/common/command_buffer.c
@@ -304,7 +304,11 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma)
u32 handle, user_cb_size;
int rc;

+ /* We use the page offset to hold the idr and thus we need to clear
+ * it before doing the mmap itself
+ */
handle = vma->vm_pgoff;
+ vma->vm_pgoff = 0;

/* reference was taken here */
cb = hl_cb_get(hdev, &hpriv->cb_mgr, handle);
--
2.17.1

2020-08-29 14:46:02

by Oded Gabbay

[permalink] [raw]
Subject: [PATCH 3/3] habanalabs: make use of dma_mmap_coherent

From: Hillf Danton <[email protected]>

Add dma_mmap_coherent() for goya and gaudi to match their use of
dma_alloc_coherent(), see the Link tag for why.

Link: https://lore.kernel.org/lkml/[email protected]/
Cc: Christoph Hellwig <[email protected]>
Cc: Zhang Li <[email protected]>
Cc: Ding Z Nan <[email protected]>
Signed-off-by: Hillf Danton <[email protected]>
Reviewed-by: Oded Gabbay <[email protected]>
Signed-off-by: Oded Gabbay <[email protected]>
---
drivers/misc/habanalabs/common/command_buffer.c | 9 ++-------
drivers/misc/habanalabs/common/habanalabs.h | 2 +-
drivers/misc/habanalabs/gaudi/gaudi.c | 7 +++----
drivers/misc/habanalabs/goya/goya.c | 7 +++----
4 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/misc/habanalabs/common/command_buffer.c b/drivers/misc/habanalabs/common/command_buffer.c
index 6563e4dfe7b6..ba63cee74050 100644
--- a/drivers/misc/habanalabs/common/command_buffer.c
+++ b/drivers/misc/habanalabs/common/command_buffer.c
@@ -300,7 +300,6 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma)
{
struct hl_device *hdev = hpriv->hdev;
struct hl_cb *cb;
- phys_addr_t address;
u32 handle, user_cb_size;
int rc;

@@ -360,12 +359,8 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma)

vma->vm_private_data = cb;

- /* Calculate address for CB */
- address = virt_to_phys((void *) (uintptr_t) cb->kernel_address);
-
- rc = hdev->asic_funcs->cb_mmap(hdev, vma, cb->kernel_address,
- address, cb->size);
-
+ rc = hdev->asic_funcs->cb_mmap(hdev, vma, (void *) cb->kernel_address,
+ cb->bus_address, cb->size);
if (rc) {
spin_lock(&cb->lock);
cb->mmap = false;
diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h
index cdb7a672ed30..6ea8ae616cf4 100644
--- a/drivers/misc/habanalabs/common/habanalabs.h
+++ b/drivers/misc/habanalabs/common/habanalabs.h
@@ -710,7 +710,7 @@ struct hl_asic_funcs {
int (*suspend)(struct hl_device *hdev);
int (*resume)(struct hl_device *hdev);
int (*cb_mmap)(struct hl_device *hdev, struct vm_area_struct *vma,
- u64 kaddress, phys_addr_t paddress, u32 size);
+ void *cpu_addr, dma_addr_t dma_addr, size_t size);
void (*ring_doorbell)(struct hl_device *hdev, u32 hw_queue_id, u32 pi);
void (*pqe_write)(struct hl_device *hdev, __le64 *pqe,
struct hl_bd *bd);
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
index 084019788e11..bc7e7e3ba3a8 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -3091,17 +3091,16 @@ static int gaudi_resume(struct hl_device *hdev)
}

static int gaudi_cb_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
- u64 kaddress, phys_addr_t paddress, u32 size)
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
{
int rc;

vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP |
VM_DONTCOPY | VM_NORESERVE;

- rc = remap_pfn_range(vma, vma->vm_start, paddress >> PAGE_SHIFT,
- size, vma->vm_page_prot);
+ rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr, dma_addr, size);
if (rc)
- dev_err(hdev->dev, "remap_pfn_range error %d", rc);
+ dev_err(hdev->dev, "dma_mmap_coherent error %d", rc);

return rc;
}
diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c
index 88847eb1b472..94b7958ba5fb 100644
--- a/drivers/misc/habanalabs/goya/goya.c
+++ b/drivers/misc/habanalabs/goya/goya.c
@@ -2661,17 +2661,16 @@ int goya_resume(struct hl_device *hdev)
}

static int goya_cb_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
- u64 kaddress, phys_addr_t paddress, u32 size)
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
{
int rc;

vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP |
VM_DONTCOPY | VM_NORESERVE;

- rc = remap_pfn_range(vma, vma->vm_start, paddress >> PAGE_SHIFT,
- size, vma->vm_page_prot);
+ rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr, dma_addr, size);
if (rc)
- dev_err(hdev->dev, "remap_pfn_range error %d", rc);
+ dev_err(hdev->dev, "dma_mmap_coherent error %d", rc);

return rc;
}
--
2.17.1