Skip to content

Commit 89b2136

Browse files
yuranuogabbay
authored andcommitted
habanalabs: add userptr_lookup node in debugfs
It is useful to have the ability to see which user address was pinned to which physical address during the initial mapping. We already have all that info stored, but no means to search this data (which may be quite large). Signed-off-by: Yuri Nudelman <[email protected]> Reviewed-by: Oded Gabbay <[email protected]> Signed-off-by: Oded Gabbay <[email protected]>
1 parent 816a6c6 commit 89b2136

File tree

4 files changed

+101
-19
lines changed

4 files changed

+101
-19
lines changed

Documentation/ABI/testing/debugfs-driver-habanalabs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ Description: Displays a list with information about the currently user
241241
pointers (user virtual addresses) that are pinned and mapped
242242
to DMA addresses
243243

244+
What: /sys/kernel/debug/habanalabs/hl<n>/userptr_lookup
245+
Date: Aug 2021
246+
KernelVersion: 5.15
247+
248+
Description: Allows to search for specific user pointers (user virtual
249+
addresses) that are pinned and mapped to DMA addresses, and see
250+
their resolution to the specific dma address.
251+
244252
What: /sys/kernel/debug/habanalabs/hl<n>/vm
245253
Date: Jan 2019
246254
KernelVersion: 5.1

drivers/misc/habanalabs/common/debugfs.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,77 @@ static int vm_show(struct seq_file *s, void *data)
320320
return 0;
321321
}
322322

323+
static int userptr_lookup_show(struct seq_file *s, void *data)
324+
{
325+
struct hl_debugfs_entry *entry = s->private;
326+
struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
327+
struct scatterlist *sg;
328+
struct hl_userptr *userptr;
329+
bool first = true;
330+
u64 total_npages, npages, sg_start, sg_end;
331+
dma_addr_t dma_addr;
332+
int i;
333+
334+
spin_lock(&dev_entry->userptr_spinlock);
335+
336+
list_for_each_entry(userptr, &dev_entry->userptr_list, debugfs_list) {
337+
if (dev_entry->userptr_lookup >= userptr->addr &&
338+
dev_entry->userptr_lookup < userptr->addr + userptr->size) {
339+
total_npages = 0;
340+
for_each_sg(userptr->sgt->sgl, sg, userptr->sgt->nents,
341+
i) {
342+
npages = hl_get_sg_info(sg, &dma_addr);
343+
sg_start = userptr->addr +
344+
total_npages * PAGE_SIZE;
345+
sg_end = userptr->addr +
346+
(total_npages + npages) * PAGE_SIZE;
347+
348+
if (dev_entry->userptr_lookup >= sg_start &&
349+
dev_entry->userptr_lookup < sg_end) {
350+
dma_addr += (dev_entry->userptr_lookup -
351+
sg_start);
352+
if (first) {
353+
first = false;
354+
seq_puts(s, "\n");
355+
seq_puts(s, " user virtual address dma address pid region start region size\n");
356+
seq_puts(s, "---------------------------------------------------------------------------------------\n");
357+
}
358+
seq_printf(s, " 0x%-18llx 0x%-16llx %-8u 0x%-16llx %-12llu\n",
359+
dev_entry->userptr_lookup,
360+
(u64)dma_addr, userptr->pid,
361+
userptr->addr, userptr->size);
362+
}
363+
total_npages += npages;
364+
}
365+
}
366+
}
367+
368+
spin_unlock(&dev_entry->userptr_spinlock);
369+
370+
if (!first)
371+
seq_puts(s, "\n");
372+
373+
return 0;
374+
}
375+
376+
static ssize_t userptr_lookup_write(struct file *file, const char __user *buf,
377+
size_t count, loff_t *f_pos)
378+
{
379+
struct seq_file *s = file->private_data;
380+
struct hl_debugfs_entry *entry = s->private;
381+
struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
382+
ssize_t rc;
383+
u64 value;
384+
385+
rc = kstrtoull_from_user(buf, count, 16, &value);
386+
if (rc)
387+
return rc;
388+
389+
dev_entry->userptr_lookup = value;
390+
391+
return count;
392+
}
393+
323394
static int mmu_show(struct seq_file *s, void *data)
324395
{
325396
struct hl_debugfs_entry *entry = s->private;
@@ -1175,6 +1246,7 @@ static const struct hl_info_list hl_debugfs_list[] = {
11751246
{"command_submission_jobs", command_submission_jobs_show, NULL},
11761247
{"userptr", userptr_show, NULL},
11771248
{"vm", vm_show, NULL},
1249+
{"userptr_lookup", userptr_lookup_show, userptr_lookup_write},
11781250
{"mmu", mmu_show, mmu_asid_va_write},
11791251
{"engines", engines_show, NULL}
11801252
};

drivers/misc/habanalabs/common/habanalabs.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,6 +1816,7 @@ struct hl_debugfs_entry {
18161816
* @state_dump_sem: protects state_dump.
18171817
* @addr: next address to read/write from/to in read/write32.
18181818
* @mmu_addr: next virtual address to translate to physical address in mmu_show.
1819+
* @userptr_lookup: the target user ptr to look up for on demand.
18191820
* @mmu_asid: ASID to use while translating in mmu_show.
18201821
* @state_dump_head: index of the latest state dump
18211822
* @i2c_bus: generic u8 debugfs file for bus value to use in i2c_data_read.
@@ -1843,6 +1844,7 @@ struct hl_dbg_device_entry {
18431844
struct rw_semaphore state_dump_sem;
18441845
u64 addr;
18451846
u64 mmu_addr;
1847+
u64 userptr_lookup;
18461848
u32 mmu_asid;
18471849
u32 state_dump_head;
18481850
u8 i2c_bus;
@@ -2647,6 +2649,23 @@ struct hl_ioctl_desc {
26472649
* Kernel module functions that can be accessed by entire module
26482650
*/
26492651

2652+
/**
2653+
* hl_get_sg_info() - get number of pages and the DMA address from SG list.
2654+
* @sg: the SG list.
2655+
* @dma_addr: pointer to DMA address to return.
2656+
*
2657+
* Calculate the number of consecutive pages described by the SG list. Take the
2658+
* offset of the address in the first page, add to it the length and round it up
2659+
* to the number of needed pages.
2660+
*/
2661+
static inline u32 hl_get_sg_info(struct scatterlist *sg, dma_addr_t *dma_addr)
2662+
{
2663+
*dma_addr = sg_dma_address(sg);
2664+
2665+
return ((((*dma_addr) & (PAGE_SIZE - 1)) + sg_dma_len(sg)) +
2666+
(PAGE_SIZE - 1)) >> PAGE_SHIFT;
2667+
}
2668+
26502669
/**
26512670
* hl_mem_area_inside_range() - Checks whether address+size are inside a range.
26522671
* @address: The start address of the area we want to validate.

drivers/misc/habanalabs/common/memory.c

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -796,23 +796,6 @@ int hl_unreserve_va_block(struct hl_device *hdev, struct hl_ctx *ctx,
796796
return rc;
797797
}
798798

799-
/**
800-
* get_sg_info() - get number of pages and the DMA address from SG list.
801-
* @sg: the SG list.
802-
* @dma_addr: pointer to DMA address to return.
803-
*
804-
* Calculate the number of consecutive pages described by the SG list. Take the
805-
* offset of the address in the first page, add to it the length and round it up
806-
* to the number of needed pages.
807-
*/
808-
static u32 get_sg_info(struct scatterlist *sg, dma_addr_t *dma_addr)
809-
{
810-
*dma_addr = sg_dma_address(sg);
811-
812-
return ((((*dma_addr) & (PAGE_SIZE - 1)) + sg_dma_len(sg)) +
813-
(PAGE_SIZE - 1)) >> PAGE_SHIFT;
814-
}
815-
816799
/**
817800
* init_phys_pg_pack_from_userptr() - initialize physical page pack from host
818801
* memory
@@ -863,7 +846,7 @@ static int init_phys_pg_pack_from_userptr(struct hl_ctx *ctx,
863846
*/
864847
total_npages = 0;
865848
for_each_sg(userptr->sgt->sgl, sg, userptr->sgt->nents, i) {
866-
npages = get_sg_info(sg, &dma_addr);
849+
npages = hl_get_sg_info(sg, &dma_addr);
867850

868851
total_npages += npages;
869852

@@ -892,7 +875,7 @@ static int init_phys_pg_pack_from_userptr(struct hl_ctx *ctx,
892875

893876
j = 0;
894877
for_each_sg(userptr->sgt->sgl, sg, userptr->sgt->nents, i) {
895-
npages = get_sg_info(sg, &dma_addr);
878+
npages = hl_get_sg_info(sg, &dma_addr);
896879

897880
/* align down to physical page size and save the offset */
898881
if (first) {

0 commit comments

Comments
 (0)