diff --git a/drivers/misc/sdma-dae/sdma_cdev.c b/drivers/misc/sdma-dae/sdma_cdev.c index e06a0140369b0409989f71ac3f6958ac489cde07..b6ee3a8a79e8d15b5bc35f4f19a243260f92a7ce 100644 --- a/drivers/misc/sdma-dae/sdma_cdev.c +++ b/drivers/misc/sdma-dae/sdma_cdev.c @@ -279,18 +279,17 @@ static int ioctl_sdma_get_chn(struct file *file, unsigned long arg) list_add(&list_node->chn_list, &data->non_share_chn_list); pchannel = pdev->channels + idx; pchannel->ida = (u32)data->ida; - spin_unlock(&pdev->channel_lock); - dev_dbg(&pdev->pdev->dev, "sdma get chn %u\n", idx); if (copy_to_user((u32 __user *)(uintptr_t)arg, &idx, sizeof(u32))) { ret = -EFAULT; goto put_chn; } + spin_unlock(&pdev->channel_lock); + dev_dbg(&pdev->pdev->dev, "sdma get chn %u\n", idx); return 0; put_chn: - spin_lock(&pdev->channel_lock); list_del(&list_node->chn_list); bitmap_set(pdev->channel_map, idx - share_chns, 1); pdev->nr_channel_used--; @@ -369,17 +368,14 @@ static int ioctl_get_near_sdmaid(struct file *file SDMA_UNUSED, unsigned long ar } for (i = 0; i < num; i++) { - spin_lock(&g_info.core_dev->device_lock); sdma_dev = g_info.core_dev->sdma_devices[i]; dev = &sdma_dev->pdev->dev; sdma_numa[i].idx = sdma_dev->idx; sdma_numa[i].pxm = sdma_dev->node_idx; if (sdma_numa[i].pxm < 0) { - spin_unlock(&g_info.core_dev->device_lock); dev_err(dev, "sdma%d PXM domain not reported!\n", sdma_numa[i].idx); return -ENODATA; } - spin_unlock(&g_info.core_dev->device_lock); dev_dbg(dev, "sdma%d PXM = %d\n", sdma_numa[i].idx, sdma_numa[i].pxm); } @@ -470,8 +466,11 @@ static int ioctl_sdma_chn_used_refcount(struct file *file, unsigned long arg) list_for_each_entry_safe(c, n, &data->share_chn_list, chn_list) { if (c->chn_idx == share_chn.chn_idx) { pchannel->cnt_used--; - if (pchannel->cnt_used == 0) + if (pchannel->cnt_used == 0) { pchannel->sync_info_base->err_cnt = 0; + pchannel->sync_info_base->lock_pid = 0; + pchannel->sync_info_base->lock = 0; + } dev_dbg(dev, "release share_chn%u\n", c->chn_idx); list_del(&c->chn_list); kfree(c); @@ -928,7 +927,6 @@ static int sdma_core_open(struct inode *inode, struct file *file) struct hisi_sdma_device *psdma_dev; dev_t sdma_dev; u32 sdma_idx; - int ret; if (g_info.core_dev->sdma_device_num == 0) { pr_err("cannot find a sdma device\n"); @@ -940,21 +938,13 @@ static int sdma_core_open(struct inode *inode, struct file *file) pr_err("wrong id of sdma device\n"); return -ENODEV; } - spin_lock(&g_info.core_dev->device_lock); psdma_dev = g_info.core_dev->sdma_devices[sdma_idx]; if (!psdma_dev) { - spin_unlock(&g_info.core_dev->device_lock); pr_err("cannot find sdma%u\n", sdma_idx); return -ENODEV; } - ret = __do_sdma_open(psdma_dev, file); - spin_unlock(&g_info.core_dev->device_lock); - if (ret != 0) { - pr_err("open sdma failed\n"); - return ret; - } - return 0; + return __do_sdma_open(psdma_dev, file); } ssize_t sdma_read_info(struct file *file, char __user *buf SDMA_UNUSED, size_t size SDMA_UNUSED, @@ -1005,12 +995,15 @@ static int sdma_dev_release(struct inode *inode SDMA_UNUSED, struct file *file) pchannel->cnt_used--; if (pchannel->sync_info_base->lock != 0 && pchannel->sync_info_base->lock_pid == (u32)current->tgid) { - dev_err(dev, "process %d exit with lock\n", current->tgid); - pchannel->sync_info_base->lock = 0; + dev_warn(dev, "process %d exit with lock\n", current->tgid); pchannel->sync_info_base->lock_pid = 0; + pchannel->sync_info_base->lock = 0; } - if (pchannel->cnt_used == 0) + if (pchannel->cnt_used == 0) { pchannel->sync_info_base->err_cnt = 0; + pchannel->sync_info_base->lock_pid = 0; + pchannel->sync_info_base->lock = 0; + } list_del(&c->chn_list); kfree(c); } @@ -1068,6 +1061,16 @@ static int remap_addr_range(u32 chn_num, u64 offset, u64 size) } } +static int sdma_vma_remap(struct vm_area_struct *vma) +{ + pr_err("sdma vma remap not supported!\n"); + return -EINVAL; +} + +static const struct vm_operations_struct sdma_vm_ops = { + .mremap = sdma_vma_remap, +}; + static int sdma_dev_mmap(struct file *file, struct vm_area_struct *vma) { struct file_open_data *data = file->private_data; @@ -1083,6 +1086,7 @@ static int sdma_dev_mmap(struct file *file, struct vm_area_struct *vma) io_base = data->psdma_dev->base_addr; size = vma->vm_end - vma->vm_start; offset = vma->vm_pgoff; + vma->vm_ops = &sdma_vm_ops; vma->vm_flags |= VM_DONTEXPAND | VM_WIPEONFORK | VM_DONTCOPY; dev_dbg(dev, "sdma total channel num = %u, user mmap offset = 0x%llx", chn_num, offset); diff --git a/drivers/misc/sdma-dae/sdma_dbg.c b/drivers/misc/sdma-dae/sdma_dbg.c index 32321d437f39a7ad744e5cb43597d07f50c6b213..f677e0e4d0aa452f443976a908599e75af5808ad 100644 --- a/drivers/misc/sdma-dae/sdma_dbg.c +++ b/drivers/misc/sdma-dae/sdma_dbg.c @@ -389,7 +389,9 @@ static int sdma_debugfs_channels_show(struct seq_file *f, void *data SDMA_UNUSED struct hisi_sdma_chn_num chn_num; struct hisi_sdma_device *sdev; struct hisi_sdma_channel *chn; + u32 dbg_mode = debug_mode; u32 chn_idx; + u32 dev_idx; u32 i; split_line(f); @@ -397,7 +399,7 @@ static int sdma_debugfs_channels_show(struct seq_file *f, void *data SDMA_UNUSED if (num == 0 || num > HISI_SDMA_MAX_DEVS) return -ENOENT; - if (debug_mode == ALL_CHANNEL_SELECTED) { + if (dbg_mode == ALL_CHANNEL_SELECTED) { for (i = 0; i < num; i++) { spin_lock(&dbg_g_info.core_dev->device_lock); sdev = dbg_g_info.core_dev->sdma_devices[i]; @@ -417,21 +419,23 @@ static int sdma_debugfs_channels_show(struct seq_file *f, void *data SDMA_UNUSED } spin_unlock(&dbg_g_info.core_dev->device_lock); } - } else if (debug_mode == SINGLE_CHANNEL_SELECTED) { - if (device_id >= HISI_SDMA_MAX_DEVS || - channel_id >= HISI_SDMA_DEFAULT_CHANNEL_NUM) { + } else if (dbg_mode == SINGLE_CHANNEL_SELECTED) { + chn_idx = channel_id; + dev_idx = device_id; + if (dev_idx >= HISI_SDMA_MAX_DEVS || + chn_idx >= HISI_SDMA_DEFAULT_CHANNEL_NUM) { seq_puts(f, "Unsupported device or channel!\n"); return -EINVAL; } spin_lock(&dbg_g_info.core_dev->device_lock); - sdev = dbg_g_info.core_dev->sdma_devices[device_id]; + sdev = dbg_g_info.core_dev->sdma_devices[dev_idx]; if (!sdev) { seq_puts(f, "sdma_devices already released!\n"); spin_unlock(&dbg_g_info.core_dev->device_lock); return -ENXIO; } chn_num = sdma_chn_info(f, sdev); - chn = sdev->channels + channel_id; + chn = sdev->channels + chn_idx; split_line(f); sdma_debugfs_get_channel_dfx(f, chn, sdev->idx); sdma_sqe_cqe_list(f, chn); diff --git a/drivers/misc/sdma-dae/sdma_main.c b/drivers/misc/sdma-dae/sdma_main.c index a54a8ddde720e7a5d7dc28265699a758e0a4d61e..9753ad8c698e1d900684c5f4ce9bbcd7ccbf8f3f 100644 --- a/drivers/misc/sdma-dae/sdma_main.c +++ b/drivers/misc/sdma-dae/sdma_main.c @@ -156,7 +156,7 @@ static void sdma_free_all_sq_cq(struct hisi_sdma_device *psdma_dev) } } -void sdma_destroy_channels(struct hisi_sdma_device *psdma_dev) +static void sdma_destroy_channels(struct hisi_sdma_device *psdma_dev) { if (!psdma_dev || !psdma_dev->channels) return; @@ -166,7 +166,7 @@ void sdma_destroy_channels(struct hisi_sdma_device *psdma_dev) psdma_dev->channels = NULL; } -int sdma_init_channels(struct hisi_sdma_device *psdma_dev) +static int sdma_init_channels(struct hisi_sdma_device *psdma_dev) { u32 chn_num = psdma_dev->nr_channel; struct hisi_sdma_channel *pchan; diff --git a/drivers/misc/sdma-dae/sdma_umem.c b/drivers/misc/sdma-dae/sdma_umem.c index 43e079209ee0998ad928ebbc474362d4794bce29..b34ac62583ee15d1796b342aaed44e566823e821 100644 --- a/drivers/misc/sdma-dae/sdma_umem.c +++ b/drivers/misc/sdma-dae/sdma_umem.c @@ -127,6 +127,8 @@ static int record_umem(u64 addr, struct list_head *list_head, int ida, u64 *cook idr = idr_alloc(&entry->pin_mem_region, pmem, 0, 0, GFP_ATOMIC); if (idr < 0) { ret = idr; + if (entry_find == false) + hash_del(&entry->node); spin_unlock(&g_hash_table->hash_lock); pr_err("Sdma failed to alloc idr!\n"); if (entry_find) @@ -155,6 +157,7 @@ static int pin_umem(u64 addr, int npages, struct list_head *p_head) size_t node_size = sizeof(struct p_list); struct page **page_list; struct p_list *cur_node; + u64 pin_addr = addr; to_pin_pages = unpin_pages = npages; while (unpin_pages != 0) { @@ -167,7 +170,7 @@ static int pin_umem(u64 addr, int npages, struct list_head *p_head) return -ENOMEM; } - pinned = pin_user_pages_fast(addr, to_pin_pages, FOLL_WRITE, page_list); + pinned = pin_user_pages_fast(pin_addr, to_pin_pages, FOLL_WRITE, page_list); if (pinned < 0) { pr_err("Sdma failed to pin user pages!\n"); ret = pinned; @@ -189,6 +192,8 @@ static int pin_umem(u64 addr, int npages, struct list_head *p_head) cur_node->pnode.pinned = pinned; list_add(&cur_node->list, p_head); unpin_pages -= to_pin_pages; + if (unpin_pages > 0) + pin_addr += to_pin_pages * PAGE_SIZE; to_pin_pages = unpin_pages; } goto exit; diff --git a/drivers/misc/sdma-dae/sdma_umem.h b/drivers/misc/sdma-dae/sdma_umem.h index fec7c70e80f38474f45dbab9c9053b01e5cb7b82..23573f653a01de9a6a223c3819bbd8182ccaca01 100644 --- a/drivers/misc/sdma-dae/sdma_umem.h +++ b/drivers/misc/sdma-dae/sdma_umem.h @@ -9,7 +9,7 @@ #define HISI_SDMA_HASH_BUCKETS_BITS 3 #define COOKIE_IDA_SHIFT 32 -#define COOKIE_IDA_MASK 0xffff +#define COOKIE_IDA_MASK 0xffffffff struct page_node { struct page **page_list;