Received: by 10.223.148.5 with SMTP id 5csp7726125wrq; Thu, 18 Jan 2018 08:46:34 -0800 (PST) X-Google-Smtp-Source: ACJfBov7FTmzE/zMjb8PoRCE+nJW82PYxDYAXdKIDog4KLWRH+aOcAakHDYn0RXq5+3teJYwcFzE X-Received: by 10.98.71.74 with SMTP id u71mr22482900pfa.45.1516293993990; Thu, 18 Jan 2018 08:46:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516293993; cv=none; d=google.com; s=arc-20160816; b=xwf7U73ceOW9IvBlawVaXn0Qhk4AXgRX4J/yjiZRAjIqAJqQtrYQc3BsF5GB/sU7uv JMAy7r5dBi5+xBndTvix730GivQqbbXPUV+PE0/X2BzTrEinf9fyiD52bLA4FprIbwSU EZ2Pt8moth3C0q4JJX8hafgWHoIxrrqge8FtSssd0Y8nkJqXyToTIkhZhfvKYeqrDw2h vGbNya6ftxnghu0UNcwxRG4U+82Ob6O7ZFMIeMCijVwbCJWaU6fjcpLKTV0sAxW2Im06 JSnvgOG8yA+VTCg8IUrZkpt8Oqevg542KVWxNw9a8de1P54gx3B4M304iKwxU5pjQedf bzKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:user-agent:in-reply-to :content-disposition:mime-version:references:subject:cc:to:from:date :arc-authentication-results; bh=QHZW3SbfWKldknCtcE3Cvh/NBvPOQJjNEngext1VUIM=; b=prWk3721n82S/EXZ6fUFeJVqBm9pxa1iQtnGiADV+6N7QPY4Os73tWFOcNs7oDuS7J IeWjW9QbpzVAs0vl+9y4CB1/InKm+tgI7RmBO63xfWspH9Mn79LLKmtaw0Xf2V34rNVj 0MaPd+ZfZxwLB7Ts4ys9AcdOWfvoQ+SSy2VlKw4Ib6i4RnVMujWrcmfALIK9F1yaROsC 25zyOnM/L1Msh9OndZ4J5OV24UpUxn2egFc90pzmFM/RN8qy/eI/A2BIjHydWJtmlEL7 ADbaeSxElE2oyFSTb5Fb1Gx533F/BUx9s6Wy05ECrF6txXLNjGEhCwEl4O6/0Csmcd/2 FdyA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b14si4306961pgu.764.2018.01.18.08.46.19; Thu, 18 Jan 2018 08:46:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755160AbeARQpT (ORCPT + 99 others); Thu, 18 Jan 2018 11:45:19 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:40438 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754513AbeARQpR (ORCPT ); Thu, 18 Jan 2018 11:45:17 -0500 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w0IGj3WN096782 for ; Thu, 18 Jan 2018 11:45:17 -0500 Received: from e36.co.us.ibm.com (e36.co.us.ibm.com [32.97.110.154]) by mx0a-001b2d01.pphosted.com with ESMTP id 2fjv02kke0-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 18 Jan 2018 11:45:15 -0500 Received: from localhost by e36.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 18 Jan 2018 09:45:12 -0700 Received: from b03cxnp08026.gho.boulder.ibm.com (9.17.130.18) by e36.co.us.ibm.com (192.168.1.136) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 18 Jan 2018 09:45:09 -0700 Received: from b03ledav003.gho.boulder.ibm.com (b03ledav003.gho.boulder.ibm.com [9.17.130.234]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w0IGj9CV4850120; Thu, 18 Jan 2018 09:45:09 -0700 Received: from b03ledav003.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1A61F6A043; Thu, 18 Jan 2018 09:45:09 -0700 (MST) Received: from suka-w540.localdomain (unknown [9.70.94.25]) by b03ledav003.gho.boulder.ibm.com (Postfix) with ESMTP id D4B6B6A03D; Thu, 18 Jan 2018 09:45:08 -0700 (MST) Received: by suka-w540.localdomain (Postfix, from userid 1000) id 8422C226D6B; Thu, 18 Jan 2018 08:45:07 -0800 (PST) Date: Thu, 18 Jan 2018 08:45:07 -0800 From: Sukadev Bhattiprolu To: Randy Dunlap Cc: Michael Ellerman , Benjamin Herrenschmidt , mikey@neuling.org, hbabu@us.ibm.com, linuxppc-dev@ozlabs.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 3/5] powerpc/ftw: Implement a simple FTW driver References: <1516157443-17716-1-git-send-email-sukadev@linux.vnet.ibm.com> <1516157443-17716-4-git-send-email-sukadev@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Operating-System: Linux 2.0.32 on an i486 User-Agent: Mutt/1.7.1 (2016-10-04) X-TM-AS-GCONF: 00 x-cbid: 18011816-0020-0000-0000-00000D5274F8 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008401; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000247; SDB=6.00976877; UDB=6.00495249; IPR=6.00756799; BA=6.00005782; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00019113; XFM=3.00000015; UTC=2018-01-18 16:45:11 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18011816-0021-0000-0000-00005FBF768F Message-Id: <20180118164507.GD5314@us.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2018-01-18_08:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1801180224 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Randy Dunlap [rdunlap@infradead.org] wrote: > > + > > + default: > > + return -EINVAL; > > + } > > +} > > Nit: some versions of gcc (or maybe clang) complain about a typed function > not always having a return value in code like above, so it is often done as: Ok. > > > +static long ftw_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) > > +{ > > + switch (cmd) { > > + > > + case FTW_SETUP: > > + return ftw_ioc_ftw_setup(fp, arg); > > + > > + default: > > + break; > > + } > > return -EINVAL; > > +} > > Do you expect to implement more ioctls? If not, just change the switch to > an if (). Maybe a couple more but changed it to an 'if' for now (and fixed an error handling issue in ftw_file_init()). Here is the updated patch. --- From 344ffbcc2cd1e64dd87249d508cf6000e6e41a0c Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Fri, 4 Aug 2017 16:45:34 -0500 Subject: [PATCH 3/5] powerpc/ftw: Implement a simple FTW driver The Fast Thread Wake-up (FTW) driver provides user space applications an interface to the low latency Core-to-Core wakeup functionality in POWER9. This mechanism allows a thread on one core to efficiently send a message to a "waiting thread" on another core on the same chip, using the Virtual Accelrator Switchboard (VAS) subsystem. This initial FTW driver implements the ioctl and mmap operations on an FTW device node. Using these operations, a pair of application threads can establish a "communication channel" and use the COPY, PASTE and WAIT instructions to wait/wake up. PATCH 5/5 documents the API and includes an example of the usage. Signed-off-by: Sukadev Bhattiprolu --- Changelog[v2] - [Michael Neuling] Rename from drop "nx" from name "nx-ftw". - [Michael Neuling] Use a single VAS_FTW_SETUP ioctl to simplify interface. - [Michael Ellerman] To work with paste emulation patch, mark PTE dirty in ->mmap() to ensure there is no fault on paste (the emulation patch must disable pagefaults when updating thread reconfig registers). - [Randy Dunlap] Minor cleanup in ftw_ioctl(). - Fix cleanup code in ftw_file_init() - Check return value from set_thread_tidr(). - Move driver drivers/misc/ftw. --- drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/ftw/Kconfig | 16 +++ drivers/misc/ftw/Makefile | 4 + drivers/misc/ftw/ftw.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 368 insertions(+) create mode 100644 drivers/misc/ftw/Kconfig create mode 100644 drivers/misc/ftw/Makefile create mode 100644 drivers/misc/ftw/ftw.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index f1a5c23..a9b161f 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -508,4 +508,5 @@ source "drivers/misc/mic/Kconfig" source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" source "drivers/misc/cxl/Kconfig" +source "drivers/misc/ftw/Kconfig" endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 5ca5f64..338668c 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_GENWQE) += genwqe/ obj-$(CONFIG_ECHO) += echo/ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o obj-$(CONFIG_CXL_BASE) += cxl/ +obj-$(CONFIG_PPC_FTW) += ftw/ obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o diff --git a/drivers/misc/ftw/Kconfig b/drivers/misc/ftw/Kconfig new file mode 100644 index 0000000..5454d40 --- /dev/null +++ b/drivers/misc/ftw/Kconfig @@ -0,0 +1,16 @@ + +config PPC_FTW + tristate "IBM Fast Thread-Wakeup (FTW)" + depends on PPC_VAS + default n + help + This enables support for IBM Fast Thread-Wakeup driver. + + The FTW driver allows applications to utilize a low overhead + core-to-core wake up mechansim in the IBM Virtual Accelerator + Switchboard (VAS) to improve performance. + + VAS adapters are found in POWER9 based systems and are required + for the FTW driver to be operational. + + If unsure, say N. diff --git a/drivers/misc/ftw/Makefile b/drivers/misc/ftw/Makefile new file mode 100644 index 0000000..2cfe566 --- /dev/null +++ b/drivers/misc/ftw/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +ccflags-y := $(call cc-disable-warning, unused-const-variable) +ccflags-$(CONFIG_PPC_WERROR) += -Werror +obj-$(CONFIG_PPC_FTW) += ftw.o diff --git a/drivers/misc/ftw/ftw.c b/drivers/misc/ftw/ftw.c new file mode 100644 index 0000000..ea02a19 --- /dev/null +++ b/drivers/misc/ftw/ftw.c @@ -0,0 +1,346 @@ +/* + * Copyright 2018 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#define pr_fmt(fmt) "ftw: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * FTW is a device driver used to provide user space access to the + * Core-to-Core aka Fast Thread Wakeup (FTW) functionality provided by + * the Virtual Accelerator Subsystem (VAS) in POWER9 systems. See also + * arch/powerpc/platforms/powernv/vas*. + * + * The driver creates the device /dev/ftw that can be used as follows: + * + * fd = open("/dev/ftw", O_RDWR); + * rc = ioctl(fd, FTW_SETUP, &attr); + * paste_addr = mmap(NULL, PAGE_SIZE, prot, MAP_SHARED, fd, 0ULL). + * vas_copy(&crb, 0, 1); + * vas_paste(paste_addr, 0, 1); + * + * where "vas_copy" and "vas_paste" are defined in copy-paste.h. + */ + +static char *ftw_dev_name = "ftw"; +static atomic_t ftw_instid = ATOMIC_INIT(0); + +/* + * Wrapper object for the ftw device - there is just one instance of + * this node in the system. + */ +struct ftw_dev { + struct cdev cdev; + struct device *device; + char *name; + dev_t devt; + struct class *class; +} ftw_device; + +/* + * One instance per open of a ftw device. Each ftw_instance is + * associated with a VAS window after the caller issues FTW_SETUP + * ioctl. + */ +struct ftw_instance { + int id; + struct vas_window *rxwin; + struct vas_window *txwin; +}; + +static char *ftw_devnode(struct device *dev, umode_t *mode) +{ + return kasprintf(GFP_KERNEL, "%s", dev_name(dev)); +} + +static int ftw_open(struct inode *inode, struct file *fp) +{ + struct ftw_instance *instance; + + instance = kzalloc(sizeof(*instance), GFP_KERNEL); + if (!instance) + return -ENOMEM; + + instance->id = atomic_inc_return(&ftw_instid); + + fp->private_data = instance; + + return 0; +} + +static int validate_ftw_setup_attr(struct ftw_setup_attr *uattr) +{ + if (uattr->version != 1 || uattr->reserved || uattr->reserved1 || + uattr->reserved2) + return -EINVAL; + + if (uattr->flags & ~FTW_FLAGS_PIN_WINDOW) + return -EINVAL; + + if (uattr->flags & FTW_FLAGS_PIN_WINDOW && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + return 0; +} + +static int ftw_ioc_ftw_setup(struct file *fp, unsigned long arg) +{ + int rc, vasid, cop; + struct vas_rx_win_attr rxattr; + struct vas_tx_win_attr txattr; + struct ftw_setup_attr uattr; + void __user *uptr = (void *)arg; + struct vas_window *rxwin, *txwin; + struct ftw_instance *instance = fp->private_data; + + rc = copy_from_user(&uattr, uptr, sizeof(uattr)); + if (rc) { + pr_debug("copy_from_user() returns %d\n", rc); + return -EFAULT; + } + + rc = validate_ftw_setup_attr(&uattr); + if (rc) + return rc; + + cop = VAS_COP_TYPE_FTW; + rc = set_thread_tidr(current); + if (rc) + return rc; + + vasid = uattr.vas_id; + + vas_init_rx_win_attr(&rxattr, cop); + rxattr.lnotify_lpid = mfspr(SPRN_LPID); + + /* + * Only caller can own the window for now. Not sure if there is need + * for process P1 to make P2 the owner of a window. If so, we need to + * find P2, make sure we have permissions, get a reference etc. + */ + rxattr.lnotify_pid = mfspr(SPRN_PID); + rxattr.lnotify_tid = mfspr(SPRN_TIDR); + + rxwin = vas_rx_win_open(vasid, cop, &rxattr); + if (IS_ERR(rxwin)) { + pr_debug("vas_rx_win_open() failed, %ld\n", PTR_ERR(rxwin)); + return PTR_ERR(rxwin); + } + + vas_init_tx_win_attr(&txattr, cop); + + txattr.lpid = mfspr(SPRN_LPID); + txattr.pidr = mfspr(SPRN_PID); + txattr.pid = task_pid_nr(current); + txattr.pswid = vas_win_id(rxwin); + + txwin = vas_tx_win_open(vasid, cop, &txattr); + if (IS_ERR(txwin)) { + pr_debug("vas_tx_win_open() failed, %ld\n", PTR_ERR(txwin)); + rc = PTR_ERR(txwin); + goto close_rxwin; + } + + instance->rxwin = rxwin; + instance->txwin = txwin; + + return 0; + +close_rxwin: + vas_win_close(rxwin); + return rc; +} + +static int ftw_release(struct inode *inode, struct file *fp) +{ + struct ftw_instance *instance; + + instance = fp->private_data; + + if (instance->txwin) + vas_win_close(instance->txwin); + if (instance->rxwin) + vas_win_close(instance->rxwin); + /* + * TODO We don't know here if user has other receive windows + * open, and can't really call clear_thread_tidr(). So, + * once the process calls set_thread_tidr(), the TIDR value + * sticks around until process exits, potentially resulting + * in an unnecessary copy in restore_sprs() when even the + * process has closed its last window. + */ + + instance->rxwin = instance->txwin = NULL; + + kfree(instance); + fp->private_data = NULL; + atomic_dec(&ftw_instid); + + return 0; +} + +static int ftw_mmap(struct file *fp, struct vm_area_struct *vma) +{ + int rc; + pgprot_t prot; + u64 paste_addr; + unsigned long pfn; + struct ftw_instance *instance = fp->private_data; + + if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) { + pr_debug("size 0x%zx, PAGE_SIZE 0x%zx\n", + (vma->vm_end - vma->vm_start), PAGE_SIZE); + return -EINVAL; + } + + /* Ensure instance has an open send window */ + if (!instance->txwin) { + pr_debug("No send window open?\n"); + return -EINVAL; + } + + paste_addr = vas_win_paste_addr(instance->txwin); + pfn = paste_addr >> PAGE_SHIFT; + + /* flags, page_prot from cxl_mmap(), except we want cachable */ + vma->vm_flags |= VM_IO | VM_PFNMAP; + vma->vm_page_prot = pgprot_cached(vma->vm_page_prot); + + /* + * We must disable page faults when emulating the paste + * instruction. To ensure that the page associated with + * the paste address is in memory, mark it dirty. + */ + prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_DIRTY); + + rc = remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, + vma->vm_end - vma->vm_start, prot); + + pr_devel("paste addr %llx at %lx, rc %d\n", paste_addr, vma->vm_start, + rc); + + set_thread_uses_vas(); + + return rc; +} + +static long ftw_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) +{ + if (cmd == FTW_SETUP) + return ftw_ioc_ftw_setup(fp, arg); + + return -EINVAL; +} + +const struct file_operations ftw_fops = { + .owner = THIS_MODULE, + .open = ftw_open, + .release = ftw_release, + .mmap = ftw_mmap, + .unlocked_ioctl = ftw_ioctl, +}; + + +int ftw_file_init(void) +{ + int rc; + dev_t devno; + + rc = alloc_chrdev_region(&ftw_device.devt, 0, 1, "ftw"); + if (rc) { + pr_debug("Unable to allocate ftw major number: %i\n", rc); + return rc; + } + + pr_devel("device allocated, dev [%i,%i]\n", + MAJOR(ftw_device.devt), MINOR(ftw_device.devt)); + + ftw_device.class = class_create(THIS_MODULE, "ftw"); + if (IS_ERR(ftw_device.class)) { + pr_debug("Unable to create FTW class\n"); + rc = PTR_ERR(ftw_device.class); + goto free_chrdev; + } + ftw_device.class->devnode = ftw_devnode; + + cdev_init(&ftw_device.cdev, &ftw_fops); + + devno = MKDEV(MAJOR(ftw_device.devt), 0); + if (cdev_add(&ftw_device.cdev, devno, 1)) { + pr_debug("cdev_add() failed\n"); + goto free_class; + } + + ftw_device.device = device_create(ftw_device.class, NULL, + devno, NULL, ftw_dev_name, MINOR(devno)); + if (IS_ERR(ftw_device.device)) { + pr_debug("Unable to create ftw-%d\n", MINOR(devno)); + goto free_cdev; + } + + pr_devel("Added dev [%d,%d]\n", MAJOR(devno), MINOR(devno)); + + return 0; + +free_cdev: + cdev_del(&ftw_device.cdev); +free_class: + class_destroy(ftw_device.class); +free_chrdev: + unregister_chrdev_region(ftw_device.devt, 1); + return rc; +} + +void ftw_file_exit(void) +{ + dev_t devno; + + cdev_del(&ftw_device.cdev); + devno = MKDEV(MAJOR(ftw_device.devt), MINOR(ftw_device.devt)); + device_destroy(ftw_device.class, devno); + + class_destroy(ftw_device.class); + unregister_chrdev_region(ftw_device.devt, 1); +} + +int __init ftw_init(void) +{ + int rc; + + rc = ftw_file_init(); + if (rc) + return rc; + + pr_info("Device initialized\n"); + + return 0; +} + +void __init ftw_exit(void) +{ + pr_devel("Device exiting\n"); + ftw_file_exit(); +} + +module_init(ftw_init); +module_exit(ftw_exit); + +MODULE_DESCRIPTION("IBM NX Fast Thread Wakeup Device"); +MODULE_AUTHOR("Sukadev Bhattiprolu "); +MODULE_LICENSE("GPL"); -- 2.7.4