Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp954774pxb; Fri, 22 Jan 2021 03:38:03 -0800 (PST) X-Google-Smtp-Source: ABdhPJwbDSyXWY2iouK6nPEPzZzCC6JZi5PAVpomr2FyxkRuEoUw7mq6bGTelGC0gn5qnsjQ79hg X-Received: by 2002:a17:907:7252:: with SMTP id ds18mr2708727ejc.239.1611315482929; Fri, 22 Jan 2021 03:38:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611315482; cv=none; d=google.com; s=arc-20160816; b=b5v5tbD/LxkitP5SCguR7Ac++J/CMR6I8Rfr110lsuiQPBzT8yQ6iCcE6QHyGdrVxw UdqLEbBDBpQ8/ji/5vaaQhUgg/IdV3ziN3lz+3cETb/LhnTL0ZKpXn5Ur8LqwniiqEAy 3rQtw7pAH+a5eJ/lfFdzH9siQaBXRsGG/xHtQI7Gku8QfONbN2mcGUL+gBVI9rdof78y y/JBPB5k4PTr0Q2J4nJZjFQEXPe8snhqrqp3sua1hdzP8lgZEhAT3C3rj9pIkNFCbleZ q8yM90MsYHmksIRNMdc/3gtr6ueOWh2engfyqtzcfLAYhW7ZFEmSr2asVnyYhxLUBmti 8AeQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to :mime-version:user-agent:date:message-id:from:cc:references:to :subject; bh=SbBPzW9kgBhsQbTpQDcOo/TrfaRtl4skJIHuofh8bg0=; b=cCMn4LvZCNYW+45QaSsxc4E+MbHFED7+Cg2eBIGI1MUUxOvcS5FfYztQhScpbns5iB gyc4yKOg47Wi1RnufDLh6bQHIM0mCrJ3s4i8ueEE9F3xTvWlTWPEtdYRuLXbexjy7EtA ZpNadIB3AlixZxIGo/cP48mIYCh0TVLDSteq9wXuhO56bqdUf9MfQ1/xzSSws2nwwt06 qzXu1LCoaa5xyYyZlY0o5JflPu26v6UGkBACkh8b+RVXs0aOvbyNTVedc29qNvUbTRto TN+Tp53Y25kNnxwYeOkjPOTbY+yNVKLLx1vJXyvxHNlyDC2OqcZLFbxGM7joSBfCmD1D FFgg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y12si2855325edv.604.2021.01.22.03.37.38; Fri, 22 Jan 2021 03:38:02 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728025AbhAVLfE (ORCPT + 99 others); Fri, 22 Jan 2021 06:35:04 -0500 Received: from szxga06-in.huawei.com ([45.249.212.32]:11431 "EHLO szxga06-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728292AbhAVLec (ORCPT ); Fri, 22 Jan 2021 06:34:32 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.59]) by szxga06-in.huawei.com (SkyGuard) with ESMTP id 4DMcZB6wYzzj7l7; Fri, 22 Jan 2021 19:32:50 +0800 (CST) Received: from [127.0.0.1] (10.40.188.87) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.498.0; Fri, 22 Jan 2021 19:33:40 +0800 Subject: Re: [PATCH] uacce: Add uacce_ctrl misc device To: Greg Kroah-Hartman References: <1611220154-90232-1-git-send-email-wangzhou1@hisilicon.com> CC: Zhangfei Gao , Arnd Bergmann , , , "Sihang Chen" From: Zhou Wang Message-ID: Date: Fri, 22 Jan 2021 19:33:40 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.7.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.40.188.87] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2021/1/21 17:44, Greg Kroah-Hartman wrote: > On Thu, Jan 21, 2021 at 05:09:14PM +0800, Zhou Wang wrote: >> When IO page fault happens, DMA performance will be affected. Pin user page >> can avoid IO page fault, this patch introduces a new char device named >> /dev/uacce_ctrl to help to maintain pin/unpin pages. User space can do >> pin/unpin pages by ioctls of an open file of /dev/uacce_ctrl, all pinned >> pages under one file will be unpinned in file release process. >> >> Signed-off-by: Zhou Wang >> Signed-off-by: Sihang Chen >> Suggested-by: Barry Song >> --- >> drivers/misc/uacce/uacce.c | 172 +++++++++++++++++++++++++++++++++++++++- >> include/uapi/misc/uacce/uacce.h | 16 ++++ >> 2 files changed, 187 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c >> index d07af4e..b8ac408 100644 >> --- a/drivers/misc/uacce/uacce.c >> +++ b/drivers/misc/uacce/uacce.c >> @@ -2,6 +2,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> @@ -12,6 +13,16 @@ static dev_t uacce_devt; >> static DEFINE_MUTEX(uacce_mutex); >> static DEFINE_XARRAY_ALLOC(uacce_xa); >> >> +struct uacce_pin_container { >> + struct xarray array; >> +}; >> + >> +struct pin_pages { >> + unsigned long first; >> + unsigned long nr_pages; >> + struct page **pages; >> +}; >> + >> static int uacce_start_queue(struct uacce_queue *q) >> { >> int ret = 0; >> @@ -497,6 +508,152 @@ void uacce_remove(struct uacce_device *uacce) >> } >> EXPORT_SYMBOL_GPL(uacce_remove); >> >> +int uacce_ctrl_open(struct inode *inode, struct file *file) >> +{ >> + struct uacce_pin_container *p; >> + >> + p = kzalloc(sizeof(*p), GFP_KERNEL); >> + if (!p) >> + return -ENOMEM; >> + file->private_data = p; >> + >> + xa_init(&p->array); >> + >> + return 0; >> +} >> + >> +int uacce_ctrl_release(struct inode *inode, struct file *file) >> +{ >> + struct uacce_pin_container *priv = file->private_data; >> + struct pin_pages *p; >> + unsigned long idx; >> + >> + xa_for_each(&priv->array, idx, p) { >> + unpin_user_pages(p->pages, p->nr_pages); >> + xa_erase(&priv->array, p->first); >> + vfree(p->pages); >> + kfree(p); >> + } >> + >> + xa_destroy(&priv->array); >> + kfree(priv); >> + >> + return 0; >> +} >> + >> +static int uacce_pin_page(struct uacce_pin_container *priv, >> + struct uacce_pin_address *addr) >> +{ >> + unsigned int flags = FOLL_FORCE | FOLL_WRITE; >> + unsigned long first, last, nr_pages; >> + struct page **pages; >> + struct pin_pages *p; >> + int ret; >> + >> + first = (addr->addr & PAGE_MASK) >> PAGE_SHIFT; >> + last = ((addr->addr + addr->size - 1) & PAGE_MASK) >> PAGE_SHIFT; >> + nr_pages = last - first + 1; >> + >> + pages = vmalloc(nr_pages * sizeof(struct page *)); >> + if (!pages) >> + return -ENOMEM; >> + >> + p = kzalloc(sizeof(*p), GFP_KERNEL); >> + if (!p) { >> + ret = -ENOMEM; >> + goto free; >> + } >> + >> + ret = pin_user_pages_fast(addr->addr & PAGE_MASK, nr_pages, >> + flags | FOLL_LONGTERM, pages); >> + if (ret != nr_pages) { >> + pr_err("uacce: Failed to pin page\n"); >> + goto free_p; >> + } >> + p->first = first; >> + p->nr_pages = nr_pages; >> + p->pages = pages; >> + >> + ret = xa_err(xa_store(&priv->array, p->first, p, GFP_KERNEL)); >> + if (ret) >> + goto unpin_pages; >> + >> + return 0; >> + >> +unpin_pages: >> + unpin_user_pages(pages, nr_pages); >> +free_p: >> + kfree(p); >> +free: >> + vfree(pages); >> + return ret; >> +} >> + >> +static int uacce_unpin_page(struct uacce_pin_container *priv, >> + struct uacce_pin_address *addr) >> +{ >> + unsigned long first, last, nr_pages; >> + struct pin_pages *p; >> + >> + first = (addr->addr & PAGE_MASK) >> PAGE_SHIFT; >> + last = ((addr->addr + addr->size - 1) & PAGE_MASK) >> PAGE_SHIFT; >> + nr_pages = last - first + 1; >> + >> + /* find pin_pages */ >> + p = xa_load(&priv->array, first); >> + if (!p) >> + return -ENODEV; >> + >> + if (p->nr_pages != nr_pages) >> + return -EINVAL; >> + >> + /* unpin */ >> + unpin_user_pages(p->pages, p->nr_pages); >> + >> + /* release resource */ >> + xa_erase(&priv->array, first); >> + vfree(p->pages); >> + kfree(p); >> + >> + return 0; >> +} >> + >> +static long uacce_ctrl_unl_ioctl(struct file *filep, unsigned int cmd, >> + unsigned long arg) >> +{ >> + struct uacce_pin_container *p = filep->private_data; >> + struct uacce_pin_address addr; >> + int ret; >> + >> + if (copy_from_user(&addr, (void __user *)arg, >> + sizeof(struct uacce_pin_address))) >> + return -EFAULT; >> + >> + switch (cmd) { >> + case UACCE_CMD_PIN: >> + return uacce_pin_page(p, &addr); >> + >> + case UACCE_CMD_UNPIN: >> + return uacce_unpin_page(p, &addr); >> + >> + default: >> + return -EINVAL; >> + } >> +} >> + >> +static const struct file_operations uacce_ctrl_fops = { >> + .owner = THIS_MODULE, >> + .open = uacce_ctrl_open, >> + .release = uacce_ctrl_release, >> + .unlocked_ioctl = uacce_ctrl_unl_ioctl, >> +}; >> + >> +static struct miscdevice uacce_ctrl_miscdev = { >> + .name = "uacce_ctrl", >> + .minor = MISC_DYNAMIC_MINOR, >> + .fops = &uacce_ctrl_fops, >> +}; >> + >> static int __init uacce_init(void) >> { >> int ret; >> @@ -507,13 +664,26 @@ static int __init uacce_init(void) >> >> ret = alloc_chrdev_region(&uacce_devt, 0, MINORMASK, UACCE_NAME); >> if (ret) >> - class_destroy(uacce_class); >> + goto destroy_class; >> + >> + ret = misc_register(&uacce_ctrl_miscdev); >> + if (ret) { >> + pr_err("uacce: ctrl dev registration failed\n"); >> + goto unregister_cdev; >> + } >> >> + return 0; >> + >> +unregister_cdev: >> + unregister_chrdev_region(uacce_devt, MINORMASK); >> +destroy_class: >> + class_destroy(uacce_class); >> return ret; >> } >> >> static __exit void uacce_exit(void) >> { >> + misc_deregister(&uacce_ctrl_miscdev); >> unregister_chrdev_region(uacce_devt, MINORMASK); >> class_destroy(uacce_class); >> } >> diff --git a/include/uapi/misc/uacce/uacce.h b/include/uapi/misc/uacce/uacce.h >> index cc71856..f9e326f 100644 >> --- a/include/uapi/misc/uacce/uacce.h >> +++ b/include/uapi/misc/uacce/uacce.h >> @@ -35,4 +35,20 @@ enum uacce_qfrt { >> UACCE_QFRT_DUS = 1, >> }; >> >> +/** >> + * struct uacce_pin_address - Expected pin user space address and size >> + * @addr: Address to pin >> + * @size: Size of pin address >> + */ >> +struct uacce_pin_address { >> + unsigned long addr; >> + unsigned long size; > > These are not valid ioctl structure members for crossing the user/kernel > boundry. Please make them work properly (i.e. use __u64 and friends). Got it, will modify this to __u64 together with other problems found by 0-day robot. Thanks, Zhou > > thanks, > > greg k-h > > . >