From patchwork Fri Jun 7 19:38:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Henrique Cerri X-Patchwork-Id: 1112218 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45LCX20f0Jz9s6w; Sat, 8 Jun 2019 05:39:14 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hZKhh-00076n-GZ; Fri, 07 Jun 2019 19:39:09 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1hZKhd-000749-4h for kernel-team@lists.ubuntu.com; Fri, 07 Jun 2019 19:39:05 +0000 Received: from mail-qt1-f198.google.com ([209.85.160.198]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1hZKhc-00070v-LY for kernel-team@lists.ubuntu.com; Fri, 07 Jun 2019 19:39:04 +0000 Received: by mail-qt1-f198.google.com with SMTP id w41so2727271qth.20 for ; Fri, 07 Jun 2019 12:39:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uCWmZ0JmhpxkywO+cZ6scS36T68+Wr3TzZcbXUFw2MU=; b=FezeHS8O8+NlQgo83vsv4815gFMKMQ/XOBKGdF62EnObci1nvuajswAWo3pM2/1kLn igJC0rUsH76pkmO/nvQwUYUQ6oJe1LLARg1T6L4AL69gcVAymU79B4hIjsUcI6WjTdNu VJeffdMfI/A+P37w+5pte0nxe2BiszQjDIuh8ZqkaMlNzmKi2eYQBFITrMZcUiBFJiKL hn438LbuSVi4rVrIOLAEbv8clcSjxIfNhxUlSvr/RRgCkAkBcfavfpt0G1ar4dZ1m7c7 gwd8HsUddmviIyxHb/53tp/NIMfVIBGNjQoxzO8IsxnQtpDR7pdL5IOxlTR1mae9cxsd W77A== X-Gm-Message-State: APjAAAWhI9iIq5KbAFz71ROFEBKSxp7oSph3q5iexNYdsU3dNYE+TKU+ MAsF0ZOdjuqKByot0XBJub092sTZEDR+JeA4xH7oT5VRw0MeSvP2QrE/7HryLJL6mZZkmh/IgCy nntFj2nMfM5gs0RGZ8YUPfFEJcDGkNki4IsvohPYt X-Received: by 2002:ac8:197a:: with SMTP id g55mr13139995qtk.320.1559936343406; Fri, 07 Jun 2019 12:39:03 -0700 (PDT) X-Google-Smtp-Source: APXvYqx8OpHIgGpYaJcPbLg7N7EAPm5WUy9koo6lZQCvXtXnFNUAWd2smTcYi8bUbbTPCChxkNBn0w== X-Received: by 2002:ac8:197a:: with SMTP id g55mr13139974qtk.320.1559936343090; Fri, 07 Jun 2019 12:39:03 -0700 (PDT) Received: from gallifrey.lan ([2804:14c:4e3:4a76:b1ae:211f:e30b:4e05]) by smtp.gmail.com with ESMTPSA id r2sm1318875qtp.8.2019.06.07.12.39.01 for (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Fri, 07 Jun 2019 12:39:02 -0700 (PDT) From: Marcelo Henrique Cerri To: kernel-team@lists.ubuntu.com Subject: [x/azure][PATCH 04/17] uio_hv_generic: support sub-channels Date: Fri, 7 Jun 2019 16:38:38 -0300 Message-Id: <20190607193851.21914-5-marcelo.cerri@canonical.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190607193851.21914-1-marcelo.cerri@canonical.com> References: <20190607193851.21914-1-marcelo.cerri@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Stephen Hemminger BugLink: http://bugs.launchpad.net/bugs/1812123 Use sysfs to allow supporting sub-channels. The userspace application makes request to host to create sub-channels and the UIO kernel driver populates the sysfs per-channel directory with a binary attribute file that can be used to read/write ring. Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman (backported from commit 37b96a4931dba07cebbf07092e55d1562155412b) [marcelo.cerri@canonical.com: fixed context in Documentation/ABI/stable/sysfs-bus-vmbus] Signed-off-by: Marcelo Henrique Cerri --- Documentation/ABI/stable/sysfs-bus-vmbus | 7 ++ Documentation/driver-api/uio-howto.rst | 5 ++ drivers/uio/uio_hv_generic.c | 89 ++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus b/Documentation/ABI/stable/sysfs-bus-vmbus index d4077cc60d55..e47777a300d3 100644 --- a/Documentation/ABI/stable/sysfs-bus-vmbus +++ b/Documentation/ABI/stable/sysfs-bus-vmbus @@ -111,3 +111,10 @@ KernelVersion: 4.14 Contact: Stephen Hemminger Description: Number of times we have taken an interrupt (incoming) Users: Debugging tools + +What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/ring +Date: January. 2018 +KernelVersion: 4.16 +Contact: Stephen Hemminger +Description: Binary file created by uio_hv_generic for ring buffer +Users: Userspace drivers diff --git a/Documentation/driver-api/uio-howto.rst b/Documentation/driver-api/uio-howto.rst index bfab29cf86c6..2663984ced86 100644 --- a/Documentation/driver-api/uio-howto.rst +++ b/Documentation/driver-api/uio-howto.rst @@ -708,6 +708,11 @@ The vmbus device regions are mapped into uio device resources: 3) Network receive buffer region 4) Network send buffer region +If a subchannel is created by a request to host, then the uio_hv_generic +device driver will create a sysfs binary file for the per-channel ring buffer. +For example: + /sys/bus/vmbus/devices/3811fe4d-0fa0-4b62-981a-74fc1084c757/channels/21/ring + Further information =================== diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index fbe7e956de60..95c1f8260450 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -137,6 +137,94 @@ static void hv_uio_rescind(struct vmbus_channel *channel) uio_event_notify(&pdata->info); } +/* + * Handle fault when looking for sub channel ring buffer + * Subchannel ring buffer is same as resource 0 which is main ring buffer + * This is derived from uio_vma_fault + */ +static int hv_uio_vma_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + void *ring_buffer = vma->vm_private_data; + struct page *page; + void *addr; + + addr = ring_buffer + (vmf->pgoff << PAGE_SHIFT); + page = virt_to_page(addr); + get_page(page); + vmf->page = page; + return 0; +} + +static const struct vm_operations_struct hv_uio_vm_ops = { + .fault = hv_uio_vma_fault, +}; + +/* Sysfs API to allow mmap of the ring buffers */ +static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + struct vm_area_struct *vma) +{ + struct vmbus_channel *channel + = container_of(kobj, struct vmbus_channel, kobj); + unsigned long requested_pages, actual_pages; + + if (vma->vm_end < vma->vm_start) + return -EINVAL; + + /* only allow 0 for now */ + if (vma->vm_pgoff > 0) + return -EINVAL; + + requested_pages = vma_pages(vma); + actual_pages = 2 * HV_RING_SIZE; + if (requested_pages > actual_pages) + return -EINVAL; + + vma->vm_private_data = channel->ringbuffer_pages; + vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; + vma->vm_ops = &hv_uio_vm_ops; + return 0; +} + +static struct bin_attribute ring_buffer_bin_attr __ro_after_init = { + .attr = { + .name = "ring", + .mode = 0600, + /* size is set at init time */ + }, + .mmap = hv_uio_ring_mmap, +}; + +/* Callback from VMBUS subystem when new channel created. */ +static void +hv_uio_new_channel(struct vmbus_channel *new_sc) +{ + struct hv_device *hv_dev = new_sc->primary_channel->device_obj; + struct device *device = &hv_dev->device; + struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev); + const size_t ring_bytes = HV_RING_SIZE * PAGE_SIZE; + int ret; + + /* Create host communication ring */ + ret = vmbus_open(new_sc, ring_bytes, ring_bytes, NULL, 0, + hv_uio_channel_cb, pdata); + if (ret) { + dev_err(device, "vmbus_open subchannel failed: %d\n", ret); + return; + } + + /* Disable interrupts on sub channel */ + new_sc->inbound.ring_buffer->interrupt_mask = 1; + set_channel_read_mode(new_sc, HV_CALL_ISR); + + ret = sysfs_create_bin_file(&new_sc->kobj, &ring_buffer_bin_attr); + if (ret) { + dev_err(device, "sysfs create ring bin file failed; %d\n", ret); + vmbus_close(new_sc); + } +} + static void hv_uio_cleanup(struct hv_device *dev, struct hv_uio_private_data *pdata) { @@ -253,6 +341,7 @@ hv_uio_probe(struct hv_device *dev, } vmbus_set_chn_rescind_callback(dev->channel, hv_uio_rescind); + vmbus_set_sc_create_callback(dev->channel, hv_uio_new_channel); hv_set_drvdata(dev, pdata);