mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-20 16:57:58 +07:00
habanalabs: add debugfs support
This patch adds debugfs support to the driver. It allows the user-space to display information that is contained in the internal structures of the driver, such as: - active command submissions - active user virtual memory mappings - number of allocated command buffers It also enables the user to perform reads and writes through Goya's PCI bars. 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>
This commit is contained in:
parent
d8dd7b0a81
commit
c216477363
126
Documentation/ABI/testing/debugfs-driver-habanalabs
Normal file
126
Documentation/ABI/testing/debugfs-driver-habanalabs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/addr
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Sets the device address to be used for read or write through
|
||||||
|
PCI bar. The acceptable value is a string that starts with "0x"
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/command_buffers
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Displays a list with information about the currently allocated
|
||||||
|
command buffers
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/command_submission
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Displays a list with information about the currently active
|
||||||
|
command submissions
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/command_submission_jobs
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Displays a list with detailed information about each JOB (CB) of
|
||||||
|
each active command submission
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/data32
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Allows the root user to read or write directly through the
|
||||||
|
device's PCI bar. Writing to this file generates a write
|
||||||
|
transaction while reading from the file generates a read
|
||||||
|
transcation. This custom interface is needed (instead of using
|
||||||
|
the generic Linux user-space PCI mapping) because the DDR bar
|
||||||
|
is very small compared to the DDR memory and only the driver can
|
||||||
|
move the bar before and after the transaction
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/device
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Enables the root user to set the device to specific state.
|
||||||
|
Valid values are "disable", "enable", "suspend", "resume".
|
||||||
|
User can read this property to see the valid values
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/i2c_addr
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Sets I2C device address for I2C transaction that is generated
|
||||||
|
by the device's CPU
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/i2c_bus
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Sets I2C bus address for I2C transaction that is generated by
|
||||||
|
the device's CPU
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/i2c_data
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Triggers an I2C transaction that is generated by the device's
|
||||||
|
CPU. Writing to this file generates a write transaction while
|
||||||
|
reading from the file generates a read transcation
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/i2c_reg
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Sets I2C register id for I2C transaction that is generated by
|
||||||
|
the device's CPU
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/led0
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Sets the state of the first S/W led on the device
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/led1
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Sets the state of the second S/W led on the device
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/led2
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Sets the state of the third S/W led on the device
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/mmu
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Displays the hop values and physical address for a given ASID
|
||||||
|
and virtual address. The user should write the ASID and VA into
|
||||||
|
the file and then read the file to get the result.
|
||||||
|
e.g. to display info about VA 0x1000 for ASID 1 you need to do:
|
||||||
|
echo "1 0x1000" > /sys/kernel/debug/habanalabs/hl0/mmu
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/set_power_state
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Sets the PCI power state. Valid values are "1" for D0 and "2"
|
||||||
|
for D3Hot
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/userptr
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Displays a list with information about the currently user
|
||||||
|
pointers (user virtual addresses) that are pinned and mapped
|
||||||
|
to DMA addresses
|
||||||
|
|
||||||
|
What: /sys/kernel/debug/habanalabs/hl<n>/vm
|
||||||
|
Date: Jan 2019
|
||||||
|
KernelVersion: 5.1
|
||||||
|
Contact: oded.gabbay@gmail.com
|
||||||
|
Description: Displays a list with information about all the active virtual
|
||||||
|
address mappings per ASID
|
@ -8,5 +8,7 @@ habanalabs-y := habanalabs_drv.o device.o context.o asid.o habanalabs_ioctl.o \
|
|||||||
command_buffer.o hw_queue.o irq.o sysfs.o hwmon.o memory.o \
|
command_buffer.o hw_queue.o irq.o sysfs.o hwmon.o memory.o \
|
||||||
command_submission.o mmu.o
|
command_submission.o mmu.o
|
||||||
|
|
||||||
|
habanalabs-$(CONFIG_DEBUG_FS) += debugfs.o
|
||||||
|
|
||||||
include $(src)/goya/Makefile
|
include $(src)/goya/Makefile
|
||||||
habanalabs-y += $(HL_GOYA_FILES)
|
habanalabs-y += $(HL_GOYA_FILES)
|
||||||
|
@ -38,6 +38,8 @@ static void cb_release(struct kref *ref)
|
|||||||
cb = container_of(ref, struct hl_cb, refcount);
|
cb = container_of(ref, struct hl_cb, refcount);
|
||||||
hdev = cb->hdev;
|
hdev = cb->hdev;
|
||||||
|
|
||||||
|
hl_debugfs_remove_cb(cb);
|
||||||
|
|
||||||
cb_do_release(hdev, cb);
|
cb_do_release(hdev, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +165,8 @@ int hl_cb_create(struct hl_device *hdev, struct hl_cb_mgr *mgr,
|
|||||||
*handle = cb->id | HL_MMAP_CB_MASK;
|
*handle = cb->id | HL_MMAP_CB_MASK;
|
||||||
*handle <<= PAGE_SHIFT;
|
*handle <<= PAGE_SHIFT;
|
||||||
|
|
||||||
|
hl_debugfs_add_cb(cb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
release_cb:
|
release_cb:
|
||||||
|
@ -149,6 +149,8 @@ static void free_job(struct hl_device *hdev, struct hl_cs_job *job)
|
|||||||
list_del(&job->cs_node);
|
list_del(&job->cs_node);
|
||||||
spin_unlock(&cs->job_lock);
|
spin_unlock(&cs->job_lock);
|
||||||
|
|
||||||
|
hl_debugfs_remove_job(hdev, job);
|
||||||
|
|
||||||
if (job->ext_queue)
|
if (job->ext_queue)
|
||||||
cs_put(cs);
|
cs_put(cs);
|
||||||
|
|
||||||
@ -212,6 +214,12 @@ static void cs_do_release(struct kref *ref)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be called before hl_ctx_put because inside we use ctx to get
|
||||||
|
* the device
|
||||||
|
*/
|
||||||
|
hl_debugfs_remove_cs(cs);
|
||||||
|
|
||||||
hl_ctx_put(cs->ctx);
|
hl_ctx_put(cs->ctx);
|
||||||
|
|
||||||
if (cs->timedout)
|
if (cs->timedout)
|
||||||
@ -480,6 +488,8 @@ static int _hl_cs_ioctl(struct hl_fpriv *hpriv, void __user *chunks,
|
|||||||
|
|
||||||
*cs_seq = cs->sequence;
|
*cs_seq = cs->sequence;
|
||||||
|
|
||||||
|
hl_debugfs_add_cs(cs);
|
||||||
|
|
||||||
/* Validate ALL the CS chunks before submitting the CS */
|
/* Validate ALL the CS chunks before submitting the CS */
|
||||||
for (i = 0, parse_cnt = 0 ; i < num_chunks ; i++, parse_cnt++) {
|
for (i = 0, parse_cnt = 0 ; i < num_chunks ; i++, parse_cnt++) {
|
||||||
struct hl_cs_chunk *chunk = &cs_chunk_array[i];
|
struct hl_cs_chunk *chunk = &cs_chunk_array[i];
|
||||||
@ -528,6 +538,8 @@ static int _hl_cs_ioctl(struct hl_fpriv *hpriv, void __user *chunks,
|
|||||||
if (job->ext_queue)
|
if (job->ext_queue)
|
||||||
cs_get(cs);
|
cs_get(cs);
|
||||||
|
|
||||||
|
hl_debugfs_add_job(hdev, job);
|
||||||
|
|
||||||
rc = cs_parser(hpriv, job);
|
rc = cs_parser(hpriv, job);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
dev_err(hdev->dev,
|
dev_err(hdev->dev,
|
||||||
|
1072
drivers/misc/habanalabs/debugfs.c
Normal file
1072
drivers/misc/habanalabs/debugfs.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,8 @@ static void hpriv_release(struct kref *ref)
|
|||||||
|
|
||||||
put_pid(hpriv->taskpid);
|
put_pid(hpriv->taskpid);
|
||||||
|
|
||||||
|
hl_debugfs_remove_file(hpriv);
|
||||||
|
|
||||||
mutex_destroy(&hpriv->restore_phase_mutex);
|
mutex_destroy(&hpriv->restore_phase_mutex);
|
||||||
|
|
||||||
kfree(hpriv);
|
kfree(hpriv);
|
||||||
@ -834,6 +836,8 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass)
|
|||||||
goto free_cb_pool;
|
goto free_cb_pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hl_debugfs_add_device(hdev);
|
||||||
|
|
||||||
if (hdev->asic_funcs->get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) {
|
if (hdev->asic_funcs->get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) {
|
||||||
dev_info(hdev->dev,
|
dev_info(hdev->dev,
|
||||||
"H/W state is dirty, must reset before initializing\n");
|
"H/W state is dirty, must reset before initializing\n");
|
||||||
@ -972,6 +976,8 @@ void hl_device_fini(struct hl_device *hdev)
|
|||||||
|
|
||||||
device_late_fini(hdev);
|
device_late_fini(hdev);
|
||||||
|
|
||||||
|
hl_debugfs_remove_device(hdev);
|
||||||
|
|
||||||
hl_sysfs_fini(hdev);
|
hl_sysfs_fini(hdev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4370,6 +4370,8 @@ int goya_context_switch(struct hl_device *hdev, u32 asid)
|
|||||||
job->user_cb_size = cb_size;
|
job->user_cb_size = cb_size;
|
||||||
job->hw_queue_id = GOYA_QUEUE_ID_DMA_0;
|
job->hw_queue_id = GOYA_QUEUE_ID_DMA_0;
|
||||||
|
|
||||||
|
hl_debugfs_add_job(hdev, job);
|
||||||
|
|
||||||
parser.ctx_id = HL_KERNEL_ASID_ID;
|
parser.ctx_id = HL_KERNEL_ASID_ID;
|
||||||
parser.cs_sequence = 0;
|
parser.cs_sequence = 0;
|
||||||
parser.job_id = job->id;
|
parser.job_id = job->id;
|
||||||
@ -4402,6 +4404,7 @@ int goya_context_switch(struct hl_device *hdev, u32 asid)
|
|||||||
|
|
||||||
free_job:
|
free_job:
|
||||||
hl_userptr_delete_list(hdev, &job->userptr_list);
|
hl_userptr_delete_list(hdev, &job->userptr_list);
|
||||||
|
hl_debugfs_remove_job(hdev, job);
|
||||||
kfree(job);
|
kfree(job);
|
||||||
cb->cs_cnt--;
|
cb->cs_cnt--;
|
||||||
|
|
||||||
@ -4432,6 +4435,106 @@ void goya_restore_phase_topology(struct hl_device *hdev)
|
|||||||
i = RREG32(mmSYNC_MNGR_SOB_OBJ_0);
|
i = RREG32(mmSYNC_MNGR_SOB_OBJ_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* goya_debugfs_read32 - read a 32bit value from a given device address
|
||||||
|
*
|
||||||
|
* @hdev: pointer to hl_device structure
|
||||||
|
* @addr: address in device
|
||||||
|
* @val: returned value
|
||||||
|
*
|
||||||
|
* In case of DDR address that is not mapped into the default aperture that
|
||||||
|
* the DDR bar exposes, the function will configure the iATU so that the DDR
|
||||||
|
* bar will be positioned at a base address that allows reading from the
|
||||||
|
* required address. Configuring the iATU during normal operation can
|
||||||
|
* lead to undefined behavior and therefore, should be done with extreme care
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int goya_debugfs_read32(struct hl_device *hdev, u64 addr, u32 *val)
|
||||||
|
{
|
||||||
|
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if ((addr >= CFG_BASE) && (addr < CFG_BASE + CFG_SIZE)) {
|
||||||
|
*val = RREG32(addr - CFG_BASE);
|
||||||
|
|
||||||
|
} else if ((addr >= SRAM_BASE_ADDR) &&
|
||||||
|
(addr < SRAM_BASE_ADDR + SRAM_SIZE)) {
|
||||||
|
|
||||||
|
*val = readl(hdev->pcie_bar[SRAM_CFG_BAR_ID] +
|
||||||
|
(addr - SRAM_BASE_ADDR));
|
||||||
|
|
||||||
|
} else if ((addr >= DRAM_PHYS_BASE) &&
|
||||||
|
(addr < DRAM_PHYS_BASE + hdev->asic_prop.dram_size)) {
|
||||||
|
|
||||||
|
u64 bar_base_addr = DRAM_PHYS_BASE +
|
||||||
|
(addr & ~(prop->dram_pci_bar_size - 0x1ull));
|
||||||
|
|
||||||
|
rc = goya_set_ddr_bar_base(hdev, bar_base_addr);
|
||||||
|
if (!rc) {
|
||||||
|
*val = readl(hdev->pcie_bar[DDR_BAR_ID] +
|
||||||
|
(addr - bar_base_addr));
|
||||||
|
|
||||||
|
rc = goya_set_ddr_bar_base(hdev, DRAM_PHYS_BASE +
|
||||||
|
(MMU_PAGE_TABLES_ADDR &
|
||||||
|
~(prop->dram_pci_bar_size - 0x1ull)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rc = -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* goya_debugfs_write32 - write a 32bit value to a given device address
|
||||||
|
*
|
||||||
|
* @hdev: pointer to hl_device structure
|
||||||
|
* @addr: address in device
|
||||||
|
* @val: returned value
|
||||||
|
*
|
||||||
|
* In case of DDR address that is not mapped into the default aperture that
|
||||||
|
* the DDR bar exposes, the function will configure the iATU so that the DDR
|
||||||
|
* bar will be positioned at a base address that allows writing to the
|
||||||
|
* required address. Configuring the iATU during normal operation can
|
||||||
|
* lead to undefined behavior and therefore, should be done with extreme care
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int goya_debugfs_write32(struct hl_device *hdev, u64 addr, u32 val)
|
||||||
|
{
|
||||||
|
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if ((addr >= CFG_BASE) && (addr < CFG_BASE + CFG_SIZE)) {
|
||||||
|
WREG32(addr - CFG_BASE, val);
|
||||||
|
|
||||||
|
} else if ((addr >= SRAM_BASE_ADDR) &&
|
||||||
|
(addr < SRAM_BASE_ADDR + SRAM_SIZE)) {
|
||||||
|
|
||||||
|
writel(val, hdev->pcie_bar[SRAM_CFG_BAR_ID] +
|
||||||
|
(addr - SRAM_BASE_ADDR));
|
||||||
|
|
||||||
|
} else if ((addr >= DRAM_PHYS_BASE) &&
|
||||||
|
(addr < DRAM_PHYS_BASE + hdev->asic_prop.dram_size)) {
|
||||||
|
|
||||||
|
u64 bar_base_addr = DRAM_PHYS_BASE +
|
||||||
|
(addr & ~(prop->dram_pci_bar_size - 0x1ull));
|
||||||
|
|
||||||
|
rc = goya_set_ddr_bar_base(hdev, bar_base_addr);
|
||||||
|
if (!rc) {
|
||||||
|
writel(val, hdev->pcie_bar[DDR_BAR_ID] +
|
||||||
|
(addr - bar_base_addr));
|
||||||
|
|
||||||
|
rc = goya_set_ddr_bar_base(hdev, DRAM_PHYS_BASE +
|
||||||
|
(MMU_PAGE_TABLES_ADDR &
|
||||||
|
~(prop->dram_pci_bar_size - 0x1ull)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rc = -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static u64 goya_read_pte(struct hl_device *hdev, u64 addr)
|
static u64 goya_read_pte(struct hl_device *hdev, u64 addr)
|
||||||
{
|
{
|
||||||
struct goya_device *goya = hdev->asic_specific;
|
struct goya_device *goya = hdev->asic_specific;
|
||||||
@ -4780,6 +4883,8 @@ static int goya_mmu_clear_pgt_range(struct hl_device *hdev)
|
|||||||
job->user_cb_size = cb_size;
|
job->user_cb_size = cb_size;
|
||||||
job->hw_queue_id = GOYA_QUEUE_ID_DMA_0;
|
job->hw_queue_id = GOYA_QUEUE_ID_DMA_0;
|
||||||
|
|
||||||
|
hl_debugfs_add_job(hdev, job);
|
||||||
|
|
||||||
parser.ctx_id = HL_KERNEL_ASID_ID;
|
parser.ctx_id = HL_KERNEL_ASID_ID;
|
||||||
parser.cs_sequence = 0;
|
parser.cs_sequence = 0;
|
||||||
parser.job_id = job->id;
|
parser.job_id = job->id;
|
||||||
@ -4808,6 +4913,7 @@ static int goya_mmu_clear_pgt_range(struct hl_device *hdev)
|
|||||||
|
|
||||||
free_job:
|
free_job:
|
||||||
hl_userptr_delete_list(hdev, &job->userptr_list);
|
hl_userptr_delete_list(hdev, &job->userptr_list);
|
||||||
|
hl_debugfs_remove_job(hdev, job);
|
||||||
kfree(job);
|
kfree(job);
|
||||||
cb->cs_cnt--;
|
cb->cs_cnt--;
|
||||||
|
|
||||||
@ -5222,6 +5328,8 @@ static const struct hl_asic_funcs goya_funcs = {
|
|||||||
.update_eq_ci = goya_update_eq_ci,
|
.update_eq_ci = goya_update_eq_ci,
|
||||||
.context_switch = goya_context_switch,
|
.context_switch = goya_context_switch,
|
||||||
.restore_phase_topology = goya_restore_phase_topology,
|
.restore_phase_topology = goya_restore_phase_topology,
|
||||||
|
.debugfs_read32 = goya_debugfs_read32,
|
||||||
|
.debugfs_write32 = goya_debugfs_write32,
|
||||||
.add_device_attr = goya_add_device_attr,
|
.add_device_attr = goya_add_device_attr,
|
||||||
.handle_eqe = goya_handle_eqe,
|
.handle_eqe = goya_handle_eqe,
|
||||||
.set_pll_profile = goya_set_pll_profile,
|
.set_pll_profile = goya_set_pll_profile,
|
||||||
|
@ -165,6 +165,10 @@ struct goya_device {
|
|||||||
u32 hw_cap_initialized;
|
u32 hw_cap_initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int goya_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus,
|
||||||
|
u8 i2c_addr, u8 i2c_reg, u32 *val);
|
||||||
|
int goya_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus,
|
||||||
|
u8 i2c_addr, u8 i2c_reg, u32 val);
|
||||||
int goya_test_cpu_queue(struct hl_device *hdev);
|
int goya_test_cpu_queue(struct hl_device *hdev);
|
||||||
int goya_send_cpu_message(struct hl_device *hdev, u32 *msg, u16 len,
|
int goya_send_cpu_message(struct hl_device *hdev, u32 *msg, u16 len,
|
||||||
u32 timeout, long *result);
|
u32 timeout, long *result);
|
||||||
@ -175,6 +179,7 @@ long goya_get_fan_speed(struct hl_device *hdev, int sensor_index, u32 attr);
|
|||||||
long goya_get_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr);
|
long goya_get_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr);
|
||||||
void goya_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
|
void goya_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
|
||||||
long value);
|
long value);
|
||||||
|
void goya_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state);
|
||||||
void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq);
|
void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq);
|
||||||
void goya_add_device_attr(struct hl_device *hdev,
|
void goya_add_device_attr(struct hl_device *hdev,
|
||||||
struct attribute_group *dev_attr_grp);
|
struct attribute_group *dev_attr_grp);
|
||||||
|
@ -238,6 +238,7 @@ struct hl_cb_mgr {
|
|||||||
* @refcount: reference counter for usage of the CB.
|
* @refcount: reference counter for usage of the CB.
|
||||||
* @hdev: pointer to device this CB belongs to.
|
* @hdev: pointer to device this CB belongs to.
|
||||||
* @lock: spinlock to protect mmap/cs flows.
|
* @lock: spinlock to protect mmap/cs flows.
|
||||||
|
* @debugfs_list: node in debugfs list of command buffers.
|
||||||
* @pool_list: node in pool list of command buffers.
|
* @pool_list: node in pool list of command buffers.
|
||||||
* @kernel_address: Holds the CB's kernel virtual address.
|
* @kernel_address: Holds the CB's kernel virtual address.
|
||||||
* @bus_address: Holds the CB's DMA address.
|
* @bus_address: Holds the CB's DMA address.
|
||||||
@ -253,6 +254,7 @@ struct hl_cb {
|
|||||||
struct kref refcount;
|
struct kref refcount;
|
||||||
struct hl_device *hdev;
|
struct hl_device *hdev;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
struct list_head debugfs_list;
|
||||||
struct list_head pool_list;
|
struct list_head pool_list;
|
||||||
u64 kernel_address;
|
u64 kernel_address;
|
||||||
dma_addr_t bus_address;
|
dma_addr_t bus_address;
|
||||||
@ -453,6 +455,8 @@ enum hl_pll_frequency {
|
|||||||
* @update_eq_ci: update event queue CI.
|
* @update_eq_ci: update event queue CI.
|
||||||
* @context_switch: called upon ASID context switch.
|
* @context_switch: called upon ASID context switch.
|
||||||
* @restore_phase_topology: clear all SOBs amd MONs.
|
* @restore_phase_topology: clear all SOBs amd MONs.
|
||||||
|
* @debugfs_read32: debug interface for reading u32 from DRAM/SRAM.
|
||||||
|
* @debugfs_write32: debug interface for writing u32 to DRAM/SRAM.
|
||||||
* @add_device_attr: add ASIC specific device attributes.
|
* @add_device_attr: add ASIC specific device attributes.
|
||||||
* @handle_eqe: handle event queue entry (IRQ) from ArmCP.
|
* @handle_eqe: handle event queue entry (IRQ) from ArmCP.
|
||||||
* @set_pll_profile: change PLL profile (manual/automatic).
|
* @set_pll_profile: change PLL profile (manual/automatic).
|
||||||
@ -521,6 +525,8 @@ struct hl_asic_funcs {
|
|||||||
void (*update_eq_ci)(struct hl_device *hdev, u32 val);
|
void (*update_eq_ci)(struct hl_device *hdev, u32 val);
|
||||||
int (*context_switch)(struct hl_device *hdev, u32 asid);
|
int (*context_switch)(struct hl_device *hdev, u32 asid);
|
||||||
void (*restore_phase_topology)(struct hl_device *hdev);
|
void (*restore_phase_topology)(struct hl_device *hdev);
|
||||||
|
int (*debugfs_read32)(struct hl_device *hdev, u64 addr, u32 *val);
|
||||||
|
int (*debugfs_write32)(struct hl_device *hdev, u64 addr, u32 val);
|
||||||
void (*add_device_attr)(struct hl_device *hdev,
|
void (*add_device_attr)(struct hl_device *hdev,
|
||||||
struct attribute_group *dev_attr_grp);
|
struct attribute_group *dev_attr_grp);
|
||||||
void (*handle_eqe)(struct hl_device *hdev,
|
void (*handle_eqe)(struct hl_device *hdev,
|
||||||
@ -584,6 +590,7 @@ struct hl_va_range {
|
|||||||
* @mem_hash_lock: protects the mem_hash.
|
* @mem_hash_lock: protects the mem_hash.
|
||||||
* @mmu_lock: protects the MMU page tables. Any change to the PGT, modifing the
|
* @mmu_lock: protects the MMU page tables. Any change to the PGT, modifing the
|
||||||
* MMU hash or walking the PGT requires talking this lock
|
* MMU hash or walking the PGT requires talking this lock
|
||||||
|
* @debugfs_list: node in debugfs list of contexts.
|
||||||
* @cs_sequence: sequence number for CS. Value is assigned to a CS and passed
|
* @cs_sequence: sequence number for CS. Value is assigned to a CS and passed
|
||||||
* to user so user could inquire about CS. It is used as
|
* to user so user could inquire about CS. It is used as
|
||||||
* index to cs_pending array.
|
* index to cs_pending array.
|
||||||
@ -608,6 +615,7 @@ struct hl_ctx {
|
|||||||
struct hl_va_range dram_va_range;
|
struct hl_va_range dram_va_range;
|
||||||
struct mutex mem_hash_lock;
|
struct mutex mem_hash_lock;
|
||||||
struct mutex mmu_lock;
|
struct mutex mmu_lock;
|
||||||
|
struct list_head debugfs_list;
|
||||||
u64 cs_sequence;
|
u64 cs_sequence;
|
||||||
spinlock_t cs_lock;
|
spinlock_t cs_lock;
|
||||||
atomic64_t dram_phys_mem;
|
atomic64_t dram_phys_mem;
|
||||||
@ -666,6 +674,7 @@ struct hl_userptr {
|
|||||||
* @fence: pointer to the fence object of this CS.
|
* @fence: pointer to the fence object of this CS.
|
||||||
* @work_tdr: delayed work node for TDR.
|
* @work_tdr: delayed work node for TDR.
|
||||||
* @mirror_node : node in device mirror list of command submissions.
|
* @mirror_node : node in device mirror list of command submissions.
|
||||||
|
* @debugfs_list: node in debugfs list of command submissions.
|
||||||
* @sequence: the sequence number of this CS.
|
* @sequence: the sequence number of this CS.
|
||||||
* @submitted: true if CS was submitted to H/W.
|
* @submitted: true if CS was submitted to H/W.
|
||||||
* @completed: true if CS was completed by device.
|
* @completed: true if CS was completed by device.
|
||||||
@ -683,6 +692,7 @@ struct hl_cs {
|
|||||||
struct dma_fence *fence;
|
struct dma_fence *fence;
|
||||||
struct delayed_work work_tdr;
|
struct delayed_work work_tdr;
|
||||||
struct list_head mirror_node;
|
struct list_head mirror_node;
|
||||||
|
struct list_head debugfs_list;
|
||||||
u64 sequence;
|
u64 sequence;
|
||||||
u8 submitted;
|
u8 submitted;
|
||||||
u8 completed;
|
u8 completed;
|
||||||
@ -701,6 +711,7 @@ struct hl_cs {
|
|||||||
* @finish_work: workqueue object to run when job is completed.
|
* @finish_work: workqueue object to run when job is completed.
|
||||||
* @userptr_list: linked-list of userptr mappings that belong to this job and
|
* @userptr_list: linked-list of userptr mappings that belong to this job and
|
||||||
* wait for completion.
|
* wait for completion.
|
||||||
|
* @debugfs_list: node in debugfs list of command submission jobs.
|
||||||
* @id: the id of this job inside a CS.
|
* @id: the id of this job inside a CS.
|
||||||
* @hw_queue_id: the id of the H/W queue this job is submitted to.
|
* @hw_queue_id: the id of the H/W queue this job is submitted to.
|
||||||
* @user_cb_size: the actual size of the CB we got from the user.
|
* @user_cb_size: the actual size of the CB we got from the user.
|
||||||
@ -714,6 +725,7 @@ struct hl_cs_job {
|
|||||||
struct hl_cb *patched_cb;
|
struct hl_cb *patched_cb;
|
||||||
struct work_struct finish_work;
|
struct work_struct finish_work;
|
||||||
struct list_head userptr_list;
|
struct list_head userptr_list;
|
||||||
|
struct list_head debugfs_list;
|
||||||
u32 id;
|
u32 id;
|
||||||
u32 hw_queue_id;
|
u32 hw_queue_id;
|
||||||
u32 user_cb_size;
|
u32 user_cb_size;
|
||||||
@ -844,6 +856,7 @@ struct hl_vm {
|
|||||||
* @ctx: current executing context.
|
* @ctx: current executing context.
|
||||||
* @ctx_mgr: context manager to handle multiple context for this FD.
|
* @ctx_mgr: context manager to handle multiple context for this FD.
|
||||||
* @cb_mgr: command buffer manager to handle multiple buffers for this FD.
|
* @cb_mgr: command buffer manager to handle multiple buffers for this FD.
|
||||||
|
* @debugfs_list: list of relevant ASIC debugfs.
|
||||||
* @refcount: number of related contexts.
|
* @refcount: number of related contexts.
|
||||||
* @restore_phase_mutex: lock for context switch and restore phase.
|
* @restore_phase_mutex: lock for context switch and restore phase.
|
||||||
*/
|
*/
|
||||||
@ -854,11 +867,90 @@ struct hl_fpriv {
|
|||||||
struct hl_ctx *ctx; /* TODO: remove for multiple ctx */
|
struct hl_ctx *ctx; /* TODO: remove for multiple ctx */
|
||||||
struct hl_ctx_mgr ctx_mgr;
|
struct hl_ctx_mgr ctx_mgr;
|
||||||
struct hl_cb_mgr cb_mgr;
|
struct hl_cb_mgr cb_mgr;
|
||||||
|
struct list_head debugfs_list;
|
||||||
struct kref refcount;
|
struct kref refcount;
|
||||||
struct mutex restore_phase_mutex;
|
struct mutex restore_phase_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DebugFS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct hl_info_list - debugfs file ops.
|
||||||
|
* @name: file name.
|
||||||
|
* @show: function to output information.
|
||||||
|
* @write: function to write to the file.
|
||||||
|
*/
|
||||||
|
struct hl_info_list {
|
||||||
|
const char *name;
|
||||||
|
int (*show)(struct seq_file *s, void *data);
|
||||||
|
ssize_t (*write)(struct file *file, const char __user *buf,
|
||||||
|
size_t count, loff_t *f_pos);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct hl_debugfs_entry - debugfs dentry wrapper.
|
||||||
|
* @dent: base debugfs entry structure.
|
||||||
|
* @info_ent: dentry realted ops.
|
||||||
|
* @dev_entry: ASIC specific debugfs manager.
|
||||||
|
*/
|
||||||
|
struct hl_debugfs_entry {
|
||||||
|
struct dentry *dent;
|
||||||
|
const struct hl_info_list *info_ent;
|
||||||
|
struct hl_dbg_device_entry *dev_entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct hl_dbg_device_entry - ASIC specific debugfs manager.
|
||||||
|
* @root: root dentry.
|
||||||
|
* @hdev: habanalabs device structure.
|
||||||
|
* @entry_arr: array of available hl_debugfs_entry.
|
||||||
|
* @file_list: list of available debugfs files.
|
||||||
|
* @file_mutex: protects file_list.
|
||||||
|
* @cb_list: list of available CBs.
|
||||||
|
* @cb_spinlock: protects cb_list.
|
||||||
|
* @cs_list: list of available CSs.
|
||||||
|
* @cs_spinlock: protects cs_list.
|
||||||
|
* @cs_job_list: list of available CB jobs.
|
||||||
|
* @cs_job_spinlock: protects cs_job_list.
|
||||||
|
* @userptr_list: list of available userptrs (virtual memory chunk descriptor).
|
||||||
|
* @userptr_spinlock: protects userptr_list.
|
||||||
|
* @ctx_mem_hash_list: list of available contexts with MMU mappings.
|
||||||
|
* @ctx_mem_hash_spinlock: protects cb_list.
|
||||||
|
* @addr: next address to read/write from/to in read/write32.
|
||||||
|
* @mmu_addr: next virtual address to translate to physical address in mmu_show.
|
||||||
|
* @mmu_asid: ASID to use while translating in mmu_show.
|
||||||
|
* @i2c_bus: generic u8 debugfs file for bus value to use in i2c_data_read.
|
||||||
|
* @i2c_bus: generic u8 debugfs file for address value to use in i2c_data_read.
|
||||||
|
* @i2c_bus: generic u8 debugfs file for register value to use in i2c_data_read.
|
||||||
|
*/
|
||||||
|
struct hl_dbg_device_entry {
|
||||||
|
struct dentry *root;
|
||||||
|
struct hl_device *hdev;
|
||||||
|
struct hl_debugfs_entry *entry_arr;
|
||||||
|
struct list_head file_list;
|
||||||
|
struct mutex file_mutex;
|
||||||
|
struct list_head cb_list;
|
||||||
|
spinlock_t cb_spinlock;
|
||||||
|
struct list_head cs_list;
|
||||||
|
spinlock_t cs_spinlock;
|
||||||
|
struct list_head cs_job_list;
|
||||||
|
spinlock_t cs_job_spinlock;
|
||||||
|
struct list_head userptr_list;
|
||||||
|
spinlock_t userptr_spinlock;
|
||||||
|
struct list_head ctx_mem_hash_list;
|
||||||
|
spinlock_t ctx_mem_hash_spinlock;
|
||||||
|
u64 addr;
|
||||||
|
u64 mmu_addr;
|
||||||
|
u32 mmu_asid;
|
||||||
|
u8 i2c_bus;
|
||||||
|
u8 i2c_addr;
|
||||||
|
u8 i2c_reg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DEVICES
|
* DEVICES
|
||||||
*/
|
*/
|
||||||
@ -953,6 +1045,7 @@ struct hl_device_reset_work {
|
|||||||
* @hwmon_dev: H/W monitor device.
|
* @hwmon_dev: H/W monitor device.
|
||||||
* @pm_mng_profile: current power management profile.
|
* @pm_mng_profile: current power management profile.
|
||||||
* @hl_chip_info: ASIC's sensors information.
|
* @hl_chip_info: ASIC's sensors information.
|
||||||
|
* @hl_debugfs: device's debugfs manager.
|
||||||
* @cb_pool: list of preallocated CBs.
|
* @cb_pool: list of preallocated CBs.
|
||||||
* @cb_pool_lock: protects the CB pool.
|
* @cb_pool_lock: protects the CB pool.
|
||||||
* @user_ctx: current user context executing.
|
* @user_ctx: current user context executing.
|
||||||
@ -1018,6 +1111,8 @@ struct hl_device {
|
|||||||
enum hl_pm_mng_profile pm_mng_profile;
|
enum hl_pm_mng_profile pm_mng_profile;
|
||||||
struct hwmon_chip_info *hl_chip_info;
|
struct hwmon_chip_info *hl_chip_info;
|
||||||
|
|
||||||
|
struct hl_dbg_device_entry hl_debugfs;
|
||||||
|
|
||||||
struct list_head cb_pool;
|
struct list_head cb_pool;
|
||||||
spinlock_t cb_pool_lock;
|
spinlock_t cb_pool_lock;
|
||||||
|
|
||||||
@ -1255,6 +1350,100 @@ void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
|
|||||||
u64 hl_get_max_power(struct hl_device *hdev);
|
u64 hl_get_max_power(struct hl_device *hdev);
|
||||||
void hl_set_max_power(struct hl_device *hdev, u64 value);
|
void hl_set_max_power(struct hl_device *hdev, u64 value);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
|
||||||
|
void hl_debugfs_init(void);
|
||||||
|
void hl_debugfs_fini(void);
|
||||||
|
void hl_debugfs_add_device(struct hl_device *hdev);
|
||||||
|
void hl_debugfs_remove_device(struct hl_device *hdev);
|
||||||
|
void hl_debugfs_add_file(struct hl_fpriv *hpriv);
|
||||||
|
void hl_debugfs_remove_file(struct hl_fpriv *hpriv);
|
||||||
|
void hl_debugfs_add_cb(struct hl_cb *cb);
|
||||||
|
void hl_debugfs_remove_cb(struct hl_cb *cb);
|
||||||
|
void hl_debugfs_add_cs(struct hl_cs *cs);
|
||||||
|
void hl_debugfs_remove_cs(struct hl_cs *cs);
|
||||||
|
void hl_debugfs_add_job(struct hl_device *hdev, struct hl_cs_job *job);
|
||||||
|
void hl_debugfs_remove_job(struct hl_device *hdev, struct hl_cs_job *job);
|
||||||
|
void hl_debugfs_add_userptr(struct hl_device *hdev, struct hl_userptr *userptr);
|
||||||
|
void hl_debugfs_remove_userptr(struct hl_device *hdev,
|
||||||
|
struct hl_userptr *userptr);
|
||||||
|
void hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx);
|
||||||
|
void hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline void __init hl_debugfs_init(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_fini(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_add_device(struct hl_device *hdev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_remove_device(struct hl_device *hdev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_add_file(struct hl_fpriv *hpriv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_remove_file(struct hl_fpriv *hpriv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_add_cb(struct hl_cb *cb)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_remove_cb(struct hl_cb *cb)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_add_cs(struct hl_cs *cs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_remove_cs(struct hl_cs *cs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_add_job(struct hl_device *hdev,
|
||||||
|
struct hl_cs_job *job)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_remove_job(struct hl_device *hdev,
|
||||||
|
struct hl_cs_job *job)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_add_userptr(struct hl_device *hdev,
|
||||||
|
struct hl_userptr *userptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_remove_userptr(struct hl_device *hdev,
|
||||||
|
struct hl_userptr *userptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev,
|
||||||
|
struct hl_ctx *ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev,
|
||||||
|
struct hl_ctx *ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* IOCTLs */
|
/* IOCTLs */
|
||||||
long hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
|
long hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
|
||||||
int hl_cb_ioctl(struct hl_fpriv *hpriv, void *data);
|
int hl_cb_ioctl(struct hl_fpriv *hpriv, void *data);
|
||||||
|
@ -146,6 +146,8 @@ int hl_device_open(struct inode *inode, struct file *filp)
|
|||||||
*/
|
*/
|
||||||
hl_device_set_frequency(hdev, PLL_HIGH);
|
hl_device_set_frequency(hdev, PLL_HIGH);
|
||||||
|
|
||||||
|
hl_debugfs_add_file(hpriv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_err:
|
out_err:
|
||||||
@ -413,17 +415,20 @@ static int __init hl_init(void)
|
|||||||
goto remove_major;
|
goto remove_major;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hl_debugfs_init();
|
||||||
|
|
||||||
rc = pci_register_driver(&hl_pci_driver);
|
rc = pci_register_driver(&hl_pci_driver);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
pr_err("failed to register pci device\n");
|
pr_err("failed to register pci device\n");
|
||||||
goto remove_class;
|
goto remove_debugfs;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("driver loaded\n");
|
pr_debug("driver loaded\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
remove_class:
|
remove_debugfs:
|
||||||
|
hl_debugfs_fini();
|
||||||
class_destroy(hl_class);
|
class_destroy(hl_class);
|
||||||
remove_major:
|
remove_major:
|
||||||
unregister_chrdev_region(MKDEV(hl_major, 0), HL_MAX_MINORS);
|
unregister_chrdev_region(MKDEV(hl_major, 0), HL_MAX_MINORS);
|
||||||
@ -437,6 +442,13 @@ static void __exit hl_exit(void)
|
|||||||
{
|
{
|
||||||
pci_unregister_driver(&hl_pci_driver);
|
pci_unregister_driver(&hl_pci_driver);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removing debugfs must be after all devices or simulator devices
|
||||||
|
* have been removed because otherwise we get a bug in the
|
||||||
|
* debugfs module for referencing NULL objects
|
||||||
|
*/
|
||||||
|
hl_debugfs_fini();
|
||||||
|
|
||||||
class_destroy(hl_class);
|
class_destroy(hl_class);
|
||||||
unregister_chrdev_region(MKDEV(hl_major, 0), HL_MAX_MINORS);
|
unregister_chrdev_region(MKDEV(hl_major, 0), HL_MAX_MINORS);
|
||||||
|
|
||||||
|
@ -1290,6 +1290,8 @@ int hl_pin_host_memory(struct hl_device *hdev, u64 addr, u32 size,
|
|||||||
goto free_sgt;
|
goto free_sgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hl_debugfs_add_userptr(hdev, userptr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_sgt:
|
free_sgt:
|
||||||
@ -1315,6 +1317,8 @@ int hl_unpin_host_memory(struct hl_device *hdev, struct hl_userptr *userptr)
|
|||||||
{
|
{
|
||||||
struct page **pages;
|
struct page **pages;
|
||||||
|
|
||||||
|
hl_debugfs_remove_userptr(hdev, userptr);
|
||||||
|
|
||||||
if (userptr->dma_mapped)
|
if (userptr->dma_mapped)
|
||||||
hdev->asic_funcs->hl_dma_unmap_sg(hdev,
|
hdev->asic_funcs->hl_dma_unmap_sg(hdev,
|
||||||
userptr->sgt->sgl,
|
userptr->sgt->sgl,
|
||||||
@ -1476,6 +1480,8 @@ int hl_vm_ctx_init_with_ranges(struct hl_ctx *ctx, u64 host_range_start,
|
|||||||
goto dram_vm_err;
|
goto dram_vm_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hl_debugfs_add_ctx_mem_hash(hdev, ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dram_vm_err:
|
dram_vm_err:
|
||||||
@ -1598,6 +1604,8 @@ void hl_vm_ctx_fini(struct hl_ctx *ctx)
|
|||||||
struct hlist_node *tmp_node;
|
struct hlist_node *tmp_node;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
hl_debugfs_remove_ctx_mem_hash(hdev, ctx);
|
||||||
|
|
||||||
if (!hash_empty(ctx->mem_hash))
|
if (!hash_empty(ctx->mem_hash))
|
||||||
dev_notice(hdev->dev, "ctx is freed while it has va in use\n");
|
dev_notice(hdev->dev, "ctx is freed while it has va in use\n");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user