Commit e64fcc91 authored by zhangshuowen96's avatar zhangshuowen96
Browse files

drivers: misc: sdma-dae: support page fault preprocess

kunpeng inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9W355


CVE: NA

----------------------------------------------------------------------

Add preprocess of memories for data-transfer: use
pin_user_pages_fast to pin memories, avoid shifting
memory pages in and out and to improve data-transfer
performance.

Signed-off-by: default avatarzhangshuowen96 <zhangshuowen@hisilicon.com>
parent 5099600b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2379,6 +2379,7 @@ CONFIG_MISC_RTSX_PCI=m
CONFIG_MISC_RTSX_USB=m
# CONFIG_HABANA_AI is not set
CONFIG_UACCE=m
CONFIG_SDMA_DAE=m
# end of Misc devices

#
+1 −0
Original line number Diff line number Diff line
@@ -498,4 +498,5 @@ source "drivers/misc/ocxl/Kconfig"
source "drivers/misc/cardreader/Kconfig"
source "drivers/misc/habanalabs/Kconfig"
source "drivers/misc/uacce/Kconfig"
source "drivers/misc/sdma-dae/Kconfig"
endmenu
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ obj-y += cardreader/
obj-$(CONFIG_PVPANIC)   	+= pvpanic.o
obj-$(CONFIG_HABANA_AI)		+= habanalabs/
obj-$(CONFIG_UACCE)		+= uacce/
obj-$(CONFIG_SDMA_DAE)		+= sdma-dae/
obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
obj-$(CONFIG_HISI_HIKEY_USB)	+= hisi_hikey_usb.o
obj-$(CONFIG_VIRT_PLAT_DEV)	+= virt_plat_dev.o
+19 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#define HISI_SDMA_CLR_NORMAL_SQE_CNT		1
#define HISI_SDMA_CLR_ERR_SQE_CNT		2

#define HISI_SDMA_HBM_CACHE_PRELOAD_MODE	0x6

struct chn_ioe_info {
	u32 ch_err_status;
	u32 ch_cqe_sqeid;
@@ -48,6 +50,12 @@ struct hisi_sdma_chn_num {
	u32 share_chn_num;
};

struct hisi_sdma_umem_info {
	uintptr_t vma;
	u32 size;
	u64 cookie;
};

struct hisi_sdma_sq_entry {
	__le32 opcode          : 8;
	__le32 sssv            : 1;
@@ -113,6 +121,14 @@ struct hisi_sdma_queue_info {
	struct chn_ioe_info ioe;
};

struct hisi_sdma_mpamcfg {
	u16    partid : 8;
	u16    pmg    : 2;
	u16    qos    : 4;
	u16    mpamid_replace_en : 1;
	u16    rsv5   : 1;
};

struct hisi_sdma_share_chn {
	u16    chn_idx;
	bool   init_flag;
@@ -168,9 +184,12 @@ struct hisi_sdma_ioctl_func_list {
#define IOCTL_SDMA_GET_CHN		_IOR('s', 2, int)
#define IOCTL_SDMA_PUT_CHN		_IOW('s', 3, int)
#define IOCTL_SDMA_GET_STREAMID		_IOR('s', 4, u32)
#define IOCTL_SDMA_PIN_UMEM		_IOWR('s', 5, struct hisi_sdma_umem_info)
#define IOCTL_SDMA_UNPIN_UMEM		_IOW('s', 6, u64)
#define IOCTL_GET_SDMA_NUM		_IOR('s', 7, int)
#define IOCTL_GET_NEAR_SDMAID		_IOR('s', 8, int)
#define IOCTL_GET_SDMA_CHN_NUM		_IOR('s', 9, struct hisi_sdma_chn_num)
#define IOCTL_SDMA_MPAMID_CFG		_IOW('s', 10, struct hisi_sdma_mpamcfg)
#define IOCTL_SDMA_CHN_USED_REFCOUNT	_IOW('s', 11, struct hisi_sdma_share_chn)
#define IOCTL_SDMA_ADD_AUTH_HT		_IOW('s', 12, struct hisi_sdma_pid_info)
#define IOCTL_SDMA_SEND_TASK		_IOWR('s', 13, struct hisi_sdma_task_info)
+80 −16
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/sort.h>

#include "sdma_hal.h"
#include "sdma_umem.h"
#include "sdma_auth.h"

static struct hisi_sdma_global_info g_info;
@@ -95,6 +96,44 @@ static int ioctl_get_sdma_num(struct file *file, unsigned long arg)

	return 0;
}
static int ioctl_sdma_unpin_umem(struct file *file, unsigned long arg)
{
	struct file_open_data *data = file->private_data;
	u64 cookie;
	int ret;

	if (copy_from_user(&cookie, (u64 __user *)(uintptr_t)arg, sizeof(u64)))
		return -EFAULT;

	ret = sdma_umem_release(cookie);
	if (ret)
		dev_err(&data->psdma_dev->pdev->dev, "umem release fail!\n");

	return ret;
}

static int ioctl_sdma_pin_umem(struct file *file, unsigned long arg)
{
	struct file_open_data *data = file->private_data;
	struct hisi_sdma_umem_info umemInfo;
	int ret;

	if (copy_from_user(&umemInfo, (struct hisi_sdma_umem_info __user *)(uintptr_t)arg,
			   sizeof(struct hisi_sdma_umem_info)))
		return -EFAULT;

	ret = sdma_umem_get((u64)umemInfo.vma, umemInfo.size, data->ida, &umemInfo.cookie);
	if (ret < 0)
		return ret;

	if (copy_to_user((struct hisi_sdma_umem_info __user *)(uintptr_t)arg, &umemInfo,
			 sizeof(struct hisi_sdma_umem_info))) {
		sdma_umem_release(umemInfo.cookie);
		return -EFAULT;
	}

	return 0;
}

static int ioctl_sdma_get_process_id(struct file *file, unsigned long arg)
{
@@ -197,6 +236,7 @@ static int ioctl_sdma_put_chn(struct file *file, unsigned long arg)
		if (c->chn_idx == idx) {
			dev_dbg(dev, "sdma put chn %d\n", idx);
			list_del(&c->chn_list);
			kfree(c);
			break;
		}
	}
@@ -282,6 +322,22 @@ static int ioctl_get_sdma_chn_num(struct file *file, unsigned long arg)
	return 0;
}

static int ioctl_sdma_mpamcfg(struct file *file, unsigned long arg)
{
	struct file_open_data *data = file->private_data;
	struct hisi_sdma_device *pdev = data->psdma_dev;
	struct hisi_sdma_mpamcfg cfg;

	if (copy_from_user(&cfg,
			   (struct hisi_sdma_mpamcfg __user *)(uintptr_t)arg,
			   sizeof(struct hisi_sdma_mpamcfg)))
		return -EFAULT;

	sdma_common_mpamid_cfg(pdev->common_base, &cfg);

	return 0;
}

static int ioctl_sdma_chn_used_refcount(struct file *file, unsigned long arg)
{
	struct file_open_data *data = file->private_data;
@@ -322,6 +378,7 @@ static int ioctl_sdma_chn_used_refcount(struct file *file, unsigned long arg)
			if (c->chn_idx == share_chn.chn_idx) {
				dev_dbg(dev, "release share_chn%d\n", c->chn_idx);
				list_del(&c->chn_list);
				kfree(c);
				break;
			}
		}
@@ -612,9 +669,12 @@ struct hisi_sdma_ioctl_func_list g_ioctl_funcs[] = {
	{IOCTL_SDMA_GET_CHN,			ioctl_sdma_get_chn},
	{IOCTL_SDMA_PUT_CHN,			ioctl_sdma_put_chn},
	{IOCTL_SDMA_GET_STREAMID,		ioctl_sdma_get_streamid},
	{IOCTL_SDMA_PIN_UMEM,			ioctl_sdma_pin_umem},
	{IOCTL_SDMA_UNPIN_UMEM,			ioctl_sdma_unpin_umem},
	{IOCTL_GET_SDMA_NUM,			ioctl_get_sdma_num},
	{IOCTL_GET_NEAR_SDMAID,			ioctl_get_near_sdmaid},
	{IOCTL_GET_SDMA_CHN_NUM,		ioctl_get_sdma_chn_num},
	{IOCTL_SDMA_MPAMID_CFG,			ioctl_sdma_mpamcfg},
	{IOCTL_SDMA_CHN_USED_REFCOUNT,		ioctl_sdma_chn_used_refcount},
	{IOCTL_SDMA_ADD_AUTH_HT,		ioctl_sdma_add_authority_ht},
	{IOCTL_SDMA_SEND_TASK,			ioctl_sdma_send_task},
@@ -691,6 +751,7 @@ static int sdma_dev_release(struct inode *inode, struct file *file)
		dev_dbg(dev, "release non_share_chn%d\n", c->chn_idx);
		bitmap_set(pdev->channel_map, c->chn_idx - share_chns, 1);
		list_del(&c->chn_list);
		kfree(c);
		pdev->nr_channel_used--;
	}

@@ -705,6 +766,7 @@ static int sdma_dev_release(struct inode *inode, struct file *file)
			pchannel->sync_info_base->lock_pid = 0;
		}
		list_del(&c->chn_list);
		kfree(c);
	}
	spin_unlock(&pdev->channel_lock);

@@ -713,6 +775,8 @@ static int sdma_dev_release(struct inode *inode, struct file *file)
		data->handle = NULL;
	}

	sdma_hash_free_entry(data->ida);
	sdma_free_authority_ht_with_pid(pid);
	ida_free(g_info.fd_ida, data->ida);

	kfree(file->private_data);
Loading