accel/amdxdna: Add a function to walk hardware contexts
Walking hardware contexts created by a process is duplicated in multiple spots. Add a function, amdxdna_hwctx_walk(), and replace all spots. hwctx_srcu and dev_lock are good enough to protect hardware context list. Remove hwctx_lock. Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> Link: https://lore.kernel.org/r/20250815171634.3417487-1-lizhi.hou@amd.compull/1354/merge
parent
cb640b2ca5
commit
c8cea4371e
|
|
@ -133,11 +133,20 @@ static void aie2_hwctx_wait_for_idle(struct amdxdna_hwctx *hwctx)
|
||||||
dma_fence_put(fence);
|
dma_fence_put(fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int aie2_hwctx_suspend_cb(struct amdxdna_hwctx *hwctx, void *arg)
|
||||||
|
{
|
||||||
|
struct amdxdna_dev *xdna = hwctx->client->xdna;
|
||||||
|
|
||||||
|
aie2_hwctx_wait_for_idle(hwctx);
|
||||||
|
aie2_hwctx_stop(xdna, hwctx, NULL);
|
||||||
|
aie2_hwctx_status_shift_stop(hwctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void aie2_hwctx_suspend(struct amdxdna_client *client)
|
void aie2_hwctx_suspend(struct amdxdna_client *client)
|
||||||
{
|
{
|
||||||
struct amdxdna_dev *xdna = client->xdna;
|
struct amdxdna_dev *xdna = client->xdna;
|
||||||
struct amdxdna_hwctx *hwctx;
|
|
||||||
unsigned long hwctx_id;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command timeout is unlikely. But if it happens, it doesn't
|
* Command timeout is unlikely. But if it happens, it doesn't
|
||||||
|
|
@ -145,19 +154,20 @@ void aie2_hwctx_suspend(struct amdxdna_client *client)
|
||||||
* and abort all commands.
|
* and abort all commands.
|
||||||
*/
|
*/
|
||||||
drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
|
drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
|
||||||
guard(mutex)(&client->hwctx_lock);
|
amdxdna_hwctx_walk(client, NULL, aie2_hwctx_suspend_cb);
|
||||||
amdxdna_for_each_hwctx(client, hwctx_id, hwctx) {
|
|
||||||
aie2_hwctx_wait_for_idle(hwctx);
|
|
||||||
aie2_hwctx_stop(xdna, hwctx, NULL);
|
|
||||||
aie2_hwctx_status_shift_stop(hwctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void aie2_hwctx_resume(struct amdxdna_client *client)
|
static int aie2_hwctx_resume_cb(struct amdxdna_hwctx *hwctx, void *arg)
|
||||||
|
{
|
||||||
|
struct amdxdna_dev *xdna = hwctx->client->xdna;
|
||||||
|
|
||||||
|
aie2_hwctx_status_restore(hwctx);
|
||||||
|
return aie2_hwctx_restart(xdna, hwctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int aie2_hwctx_resume(struct amdxdna_client *client)
|
||||||
{
|
{
|
||||||
struct amdxdna_dev *xdna = client->xdna;
|
struct amdxdna_dev *xdna = client->xdna;
|
||||||
struct amdxdna_hwctx *hwctx;
|
|
||||||
unsigned long hwctx_id;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The resume path cannot guarantee that mailbox channel can be
|
* The resume path cannot guarantee that mailbox channel can be
|
||||||
|
|
@ -165,11 +175,7 @@ void aie2_hwctx_resume(struct amdxdna_client *client)
|
||||||
* mailbox channel, error will return.
|
* mailbox channel, error will return.
|
||||||
*/
|
*/
|
||||||
drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
|
drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
|
||||||
guard(mutex)(&client->hwctx_lock);
|
return amdxdna_hwctx_walk(client, NULL, aie2_hwctx_resume_cb);
|
||||||
amdxdna_for_each_hwctx(client, hwctx_id, hwctx) {
|
|
||||||
aie2_hwctx_status_restore(hwctx);
|
|
||||||
aie2_hwctx_restart(xdna, hwctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -290,18 +290,25 @@ int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u6
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int amdxdna_hwctx_col_map(struct amdxdna_hwctx *hwctx, void *arg)
|
||||||
|
{
|
||||||
|
u32 *bitmap = arg;
|
||||||
|
|
||||||
|
*bitmap |= GENMASK(hwctx->start_col + hwctx->num_col - 1, hwctx->start_col);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf,
|
int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf,
|
||||||
u32 size, u32 *cols_filled)
|
u32 size, u32 *cols_filled)
|
||||||
{
|
{
|
||||||
DECLARE_AIE2_MSG(aie_column_info, MSG_OP_QUERY_COL_STATUS);
|
DECLARE_AIE2_MSG(aie_column_info, MSG_OP_QUERY_COL_STATUS);
|
||||||
struct amdxdna_dev *xdna = ndev->xdna;
|
struct amdxdna_dev *xdna = ndev->xdna;
|
||||||
struct amdxdna_client *client;
|
struct amdxdna_client *client;
|
||||||
struct amdxdna_hwctx *hwctx;
|
|
||||||
unsigned long hwctx_id;
|
|
||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
u32 aie_bitmap = 0;
|
u32 aie_bitmap = 0;
|
||||||
u8 *buff_addr;
|
u8 *buff_addr;
|
||||||
int ret, idx;
|
int ret;
|
||||||
|
|
||||||
buff_addr = dma_alloc_noncoherent(xdna->ddev.dev, size, &dma_addr,
|
buff_addr = dma_alloc_noncoherent(xdna->ddev.dev, size, &dma_addr,
|
||||||
DMA_FROM_DEVICE, GFP_KERNEL);
|
DMA_FROM_DEVICE, GFP_KERNEL);
|
||||||
|
|
@ -309,12 +316,8 @@ int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Go through each hardware context and mark the AIE columns that are active */
|
/* Go through each hardware context and mark the AIE columns that are active */
|
||||||
list_for_each_entry(client, &xdna->client_list, node) {
|
list_for_each_entry(client, &xdna->client_list, node)
|
||||||
idx = srcu_read_lock(&client->hwctx_srcu);
|
amdxdna_hwctx_walk(client, &aie_bitmap, amdxdna_hwctx_col_map);
|
||||||
amdxdna_for_each_hwctx(client, hwctx_id, hwctx)
|
|
||||||
aie_bitmap |= amdxdna_hwctx_col_map(hwctx);
|
|
||||||
srcu_read_unlock(&client->hwctx_srcu, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
*cols_filled = 0;
|
*cols_filled = 0;
|
||||||
req.dump_buff_addr = dma_addr;
|
req.dump_buff_addr = dma_addr;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include <drm/drm_managed.h>
|
#include <drm/drm_managed.h>
|
||||||
#include <drm/drm_print.h>
|
#include <drm/drm_print.h>
|
||||||
#include <drm/gpu_scheduler.h>
|
#include <drm/gpu_scheduler.h>
|
||||||
|
#include <linux/cleanup.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include <linux/iommu.h>
|
#include <linux/iommu.h>
|
||||||
|
|
@ -465,8 +466,11 @@ static int aie2_hw_resume(struct amdxdna_dev *xdna)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(client, &xdna->client_list, node)
|
list_for_each_entry(client, &xdna->client_list, node) {
|
||||||
aie2_hwctx_resume(client);
|
ret = aie2_hwctx_resume(client);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -779,65 +783,56 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aie2_get_hwctx_status(struct amdxdna_client *client,
|
static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg)
|
||||||
struct amdxdna_drm_get_info *args)
|
|
||||||
{
|
{
|
||||||
struct amdxdna_drm_query_hwctx __user *buf;
|
struct amdxdna_drm_query_hwctx __user *buf, *tmp __free(kfree) = NULL;
|
||||||
struct amdxdna_dev *xdna = client->xdna;
|
struct amdxdna_drm_get_info *get_info_args = arg;
|
||||||
struct amdxdna_drm_query_hwctx *tmp;
|
|
||||||
struct amdxdna_client *tmp_client;
|
|
||||||
struct amdxdna_hwctx *hwctx;
|
|
||||||
unsigned long hwctx_id;
|
|
||||||
bool overflow = false;
|
|
||||||
u32 req_bytes = 0;
|
|
||||||
u32 hw_i = 0;
|
|
||||||
int ret = 0;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
|
if (get_info_args->buffer_size < sizeof(*tmp))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
|
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
buf = u64_to_user_ptr(args->buffer);
|
tmp->pid = hwctx->client->pid;
|
||||||
|
tmp->context_id = hwctx->id;
|
||||||
|
tmp->start_col = hwctx->start_col;
|
||||||
|
tmp->num_col = hwctx->num_col;
|
||||||
|
tmp->command_submissions = hwctx->priv->seq;
|
||||||
|
tmp->command_completions = hwctx->priv->completed;
|
||||||
|
|
||||||
|
buf = u64_to_user_ptr(get_info_args->buffer);
|
||||||
|
|
||||||
|
if (copy_to_user(buf, tmp, sizeof(*tmp)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
get_info_args->buffer += sizeof(*tmp);
|
||||||
|
get_info_args->buffer_size -= sizeof(*tmp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aie2_get_hwctx_status(struct amdxdna_client *client,
|
||||||
|
struct amdxdna_drm_get_info *args)
|
||||||
|
{
|
||||||
|
struct amdxdna_dev *xdna = client->xdna;
|
||||||
|
struct amdxdna_drm_get_info info_args;
|
||||||
|
struct amdxdna_client *tmp_client;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
|
||||||
|
|
||||||
|
info_args.buffer = args->buffer;
|
||||||
|
info_args.buffer_size = args->buffer_size;
|
||||||
|
|
||||||
list_for_each_entry(tmp_client, &xdna->client_list, node) {
|
list_for_each_entry(tmp_client, &xdna->client_list, node) {
|
||||||
idx = srcu_read_lock(&tmp_client->hwctx_srcu);
|
ret = amdxdna_hwctx_walk(tmp_client, &info_args, aie2_hwctx_status_cb);
|
||||||
amdxdna_for_each_hwctx(tmp_client, hwctx_id, hwctx) {
|
if (ret)
|
||||||
req_bytes += sizeof(*tmp);
|
break;
|
||||||
if (args->buffer_size < req_bytes) {
|
|
||||||
/* Continue iterating to get the required size */
|
|
||||||
overflow = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(tmp, 0, sizeof(*tmp));
|
|
||||||
tmp->pid = tmp_client->pid;
|
|
||||||
tmp->context_id = hwctx->id;
|
|
||||||
tmp->start_col = hwctx->start_col;
|
|
||||||
tmp->num_col = hwctx->num_col;
|
|
||||||
tmp->command_submissions = hwctx->priv->seq;
|
|
||||||
tmp->command_completions = hwctx->priv->completed;
|
|
||||||
|
|
||||||
if (copy_to_user(&buf[hw_i], tmp, sizeof(*tmp))) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
srcu_read_unlock(&tmp_client->hwctx_srcu, idx);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
hw_i++;
|
|
||||||
}
|
|
||||||
srcu_read_unlock(&tmp_client->hwctx_srcu, idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overflow) {
|
args->buffer_size = (u32)(info_args.buffer - args->buffer);
|
||||||
XDNA_ERR(xdna, "Invalid buffer size. Given: %u Need: %u.",
|
|
||||||
args->buffer_size, req_bytes);
|
|
||||||
ret = -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
kfree(tmp);
|
|
||||||
args->buffer_size = req_bytes;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx);
|
||||||
void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx);
|
void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx);
|
||||||
int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *buf, u32 size);
|
int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *buf, u32 size);
|
||||||
void aie2_hwctx_suspend(struct amdxdna_client *client);
|
void aie2_hwctx_suspend(struct amdxdna_client *client);
|
||||||
void aie2_hwctx_resume(struct amdxdna_client *client);
|
int aie2_hwctx_resume(struct amdxdna_client *client);
|
||||||
int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, u64 *seq);
|
int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, u64 *seq);
|
||||||
void aie2_hmm_invalidate(struct amdxdna_gem_obj *abo, unsigned long cur_seq);
|
void aie2_hmm_invalidate(struct amdxdna_gem_obj *abo, unsigned long cur_seq);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,14 +68,30 @@ static void amdxdna_hwctx_destroy_rcu(struct amdxdna_hwctx *hwctx,
|
||||||
synchronize_srcu(ss);
|
synchronize_srcu(ss);
|
||||||
|
|
||||||
/* At this point, user is not able to submit new commands */
|
/* At this point, user is not able to submit new commands */
|
||||||
mutex_lock(&xdna->dev_lock);
|
|
||||||
xdna->dev_info->ops->hwctx_fini(hwctx);
|
xdna->dev_info->ops->hwctx_fini(hwctx);
|
||||||
mutex_unlock(&xdna->dev_lock);
|
|
||||||
|
|
||||||
kfree(hwctx->name);
|
kfree(hwctx->name);
|
||||||
kfree(hwctx);
|
kfree(hwctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int amdxdna_hwctx_walk(struct amdxdna_client *client, void *arg,
|
||||||
|
int (*walk)(struct amdxdna_hwctx *hwctx, void *arg))
|
||||||
|
{
|
||||||
|
struct amdxdna_hwctx *hwctx;
|
||||||
|
unsigned long hwctx_id;
|
||||||
|
int ret = 0, idx;
|
||||||
|
|
||||||
|
idx = srcu_read_lock(&client->hwctx_srcu);
|
||||||
|
amdxdna_for_each_hwctx(client, hwctx_id, hwctx) {
|
||||||
|
ret = walk(hwctx, arg);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
srcu_read_unlock(&client->hwctx_srcu, idx);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size)
|
void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size)
|
||||||
{
|
{
|
||||||
struct amdxdna_cmd *cmd = abo->mem.kva;
|
struct amdxdna_cmd *cmd = abo->mem.kva;
|
||||||
|
|
@ -126,16 +142,12 @@ void amdxdna_hwctx_remove_all(struct amdxdna_client *client)
|
||||||
struct amdxdna_hwctx *hwctx;
|
struct amdxdna_hwctx *hwctx;
|
||||||
unsigned long hwctx_id;
|
unsigned long hwctx_id;
|
||||||
|
|
||||||
mutex_lock(&client->hwctx_lock);
|
|
||||||
amdxdna_for_each_hwctx(client, hwctx_id, hwctx) {
|
amdxdna_for_each_hwctx(client, hwctx_id, hwctx) {
|
||||||
XDNA_DBG(client->xdna, "PID %d close HW context %d",
|
XDNA_DBG(client->xdna, "PID %d close HW context %d",
|
||||||
client->pid, hwctx->id);
|
client->pid, hwctx->id);
|
||||||
xa_erase(&client->hwctx_xa, hwctx->id);
|
xa_erase(&client->hwctx_xa, hwctx->id);
|
||||||
mutex_unlock(&client->hwctx_lock);
|
|
||||||
amdxdna_hwctx_destroy_rcu(hwctx, &client->hwctx_srcu);
|
amdxdna_hwctx_destroy_rcu(hwctx, &client->hwctx_srcu);
|
||||||
mutex_lock(&client->hwctx_lock);
|
|
||||||
}
|
}
|
||||||
mutex_unlock(&client->hwctx_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int amdxdna_drm_create_hwctx_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
int amdxdna_drm_create_hwctx_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||||
|
|
@ -225,6 +237,7 @@ int amdxdna_drm_destroy_hwctx_ioctl(struct drm_device *dev, void *data, struct d
|
||||||
if (!drm_dev_enter(dev, &idx))
|
if (!drm_dev_enter(dev, &idx))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
mutex_lock(&xdna->dev_lock);
|
||||||
hwctx = xa_erase(&client->hwctx_xa, args->handle);
|
hwctx = xa_erase(&client->hwctx_xa, args->handle);
|
||||||
if (!hwctx) {
|
if (!hwctx) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|
@ -241,6 +254,7 @@ int amdxdna_drm_destroy_hwctx_ioctl(struct drm_device *dev, void *data, struct d
|
||||||
|
|
||||||
XDNA_DBG(xdna, "PID %d destroyed HW context %d", client->pid, args->handle);
|
XDNA_DBG(xdna, "PID %d destroyed HW context %d", client->pid, args->handle);
|
||||||
out:
|
out:
|
||||||
|
mutex_unlock(&xdna->dev_lock);
|
||||||
drm_dev_exit(idx);
|
drm_dev_exit(idx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,14 +139,10 @@ amdxdna_cmd_get_state(struct amdxdna_gem_obj *abo)
|
||||||
void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size);
|
void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size);
|
||||||
int amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo);
|
int amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo);
|
||||||
|
|
||||||
static inline u32 amdxdna_hwctx_col_map(struct amdxdna_hwctx *hwctx)
|
|
||||||
{
|
|
||||||
return GENMASK(hwctx->start_col + hwctx->num_col - 1,
|
|
||||||
hwctx->start_col);
|
|
||||||
}
|
|
||||||
|
|
||||||
void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job);
|
void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job);
|
||||||
void amdxdna_hwctx_remove_all(struct amdxdna_client *client);
|
void amdxdna_hwctx_remove_all(struct amdxdna_client *client);
|
||||||
|
int amdxdna_hwctx_walk(struct amdxdna_client *client, void *arg,
|
||||||
|
int (*walk)(struct amdxdna_hwctx *hwctx, void *arg));
|
||||||
|
|
||||||
int amdxdna_cmd_submit(struct amdxdna_client *client,
|
int amdxdna_cmd_submit(struct amdxdna_client *client,
|
||||||
u32 cmd_bo_hdls, u32 *arg_bo_hdls, u32 arg_bo_cnt,
|
u32 cmd_bo_hdls, u32 *arg_bo_hdls, u32 arg_bo_cnt,
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp)
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto unbind_sva;
|
goto unbind_sva;
|
||||||
}
|
}
|
||||||
mutex_init(&client->hwctx_lock);
|
|
||||||
init_srcu_struct(&client->hwctx_srcu);
|
init_srcu_struct(&client->hwctx_srcu);
|
||||||
xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
|
xa_init_flags(&client->hwctx_xa, XA_FLAGS_ALLOC);
|
||||||
mutex_init(&client->mm_lock);
|
mutex_init(&client->mm_lock);
|
||||||
|
|
@ -116,7 +115,6 @@ static void amdxdna_drm_close(struct drm_device *ddev, struct drm_file *filp)
|
||||||
|
|
||||||
xa_destroy(&client->hwctx_xa);
|
xa_destroy(&client->hwctx_xa);
|
||||||
cleanup_srcu_struct(&client->hwctx_srcu);
|
cleanup_srcu_struct(&client->hwctx_srcu);
|
||||||
mutex_destroy(&client->hwctx_lock);
|
|
||||||
mutex_destroy(&client->mm_lock);
|
mutex_destroy(&client->mm_lock);
|
||||||
if (client->dev_heap)
|
if (client->dev_heap)
|
||||||
drm_gem_object_put(to_gobj(client->dev_heap));
|
drm_gem_object_put(to_gobj(client->dev_heap));
|
||||||
|
|
@ -142,8 +140,8 @@ static int amdxdna_flush(struct file *f, fl_owner_t id)
|
||||||
|
|
||||||
mutex_lock(&xdna->dev_lock);
|
mutex_lock(&xdna->dev_lock);
|
||||||
list_del_init(&client->node);
|
list_del_init(&client->node);
|
||||||
mutex_unlock(&xdna->dev_lock);
|
|
||||||
amdxdna_hwctx_remove_all(client);
|
amdxdna_hwctx_remove_all(client);
|
||||||
|
mutex_unlock(&xdna->dev_lock);
|
||||||
|
|
||||||
drm_dev_exit(idx);
|
drm_dev_exit(idx);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -330,11 +328,8 @@ static void amdxdna_remove(struct pci_dev *pdev)
|
||||||
struct amdxdna_client, node);
|
struct amdxdna_client, node);
|
||||||
while (client) {
|
while (client) {
|
||||||
list_del_init(&client->node);
|
list_del_init(&client->node);
|
||||||
mutex_unlock(&xdna->dev_lock);
|
|
||||||
|
|
||||||
amdxdna_hwctx_remove_all(client);
|
amdxdna_hwctx_remove_all(client);
|
||||||
|
|
||||||
mutex_lock(&xdna->dev_lock);
|
|
||||||
client = list_first_entry_or_null(&xdna->client_list,
|
client = list_first_entry_or_null(&xdna->client_list,
|
||||||
struct amdxdna_client, node);
|
struct amdxdna_client, node);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,8 +116,6 @@ struct amdxdna_device_id {
|
||||||
struct amdxdna_client {
|
struct amdxdna_client {
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
struct mutex hwctx_lock; /* protect hwctx */
|
|
||||||
/* do NOT wait this srcu when hwctx_lock is held */
|
|
||||||
struct srcu_struct hwctx_srcu;
|
struct srcu_struct hwctx_srcu;
|
||||||
struct xarray hwctx_xa;
|
struct xarray hwctx_xa;
|
||||||
u32 next_hwctxid;
|
u32 next_hwctxid;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue