From patchwork Mon Aug 7 12:22:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Andrushchenko X-Patchwork-Id: 9885243 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7333C60363 for ; Mon, 7 Aug 2017 12:25:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 64B1428670 for ; Mon, 7 Aug 2017 12:25:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 59B3528676; Mon, 7 Aug 2017 12:25:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.6 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E342A28670 for ; Mon, 7 Aug 2017 12:25:27 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1deh3x-0007qm-6J; Mon, 07 Aug 2017 12:23:13 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1deh3w-0007pA-Ah for xen-devel@lists.xen.org; Mon, 07 Aug 2017 12:23:12 +0000 Received: from [85.158.137.68] by server-5.bemta-3.messagelabs.com id DE/95-02181-FAB58895; Mon, 07 Aug 2017 12:23:11 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrPIsWRWlGSWpSXmKPExsVyMfS6k+666I5 Ig2vvTSyWfFzM4sDocXT3b6YAxijWzLyk/IoE1oxv+/qYCtq1K+bevMnawPhGpYuRi0NIoJ9R 4sbxR2wgDovASxaJpXe6WUAcCYF+Von/F+8BORxATpzEmm9lEGa5xN+vYl2MnEDNihJfn01ng hi0iknixLsmJpAEm4CRxPIbP1hAbBGBCIljjz+wgdjMAqUSN/bPYe5iZOcQFvCXOJwHEmURUJ XYsGYNWDWvgKPE9gdrwKolBOQkbp7rZAaxOQWcJJ73PmaDWOso8fnMDNYJjAILGBlWMWoUpxa VpRbpGlroJRVlpmeU5CZm5ugaGhjr5aYWFyemp+YkJhXrJefnbmIEBlU9AwPjDsbfpz0PMUpy MCmJ8savaIsU4kvKT6nMSCzOiC8qzUktPsQow8GhJMH7OrIjUkiwKDU9tSItMwcY3jBpCQ4eJ RFelSigNG9xQWJucWY6ROoUoz3HlSvrvjBxbFi9HkhOObAdSL6a8P8bkxBLXn5eqpQ4bxhImw BIW0ZpHtxQWDxeYpSVEuZlZGBgEOIpSC3KzSxBlX/FKM7BqCTMqwYyhSczrwRu9yugs5iAznq T2ApyVkkiQkqqgTHlEFNmZEG8YNzr9sY5U7oWCR7hZxPiFt/84PPk+LWbNz+7FbLCbM7G01nJ T30l+dLytZTerjQTdfp2ivvodJ7vjNXNIvYOr/t+Tp/npSe6rX/Lppv386dLPtDapscy34L9Y FL6lA96PLXy38wzflyuX3Bo6bXJk1++Me74tiSh+rRe1Iq5/olKLMUZiYZazEXFiQDDmn61wg IAAA== X-Env-Sender: andr2000@gmail.com X-Msg-Ref: server-5.tower-31.messagelabs.com!1502108590!105675531!1 X-Originating-IP: [209.85.215.66] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.25; banners=-,-,- X-VirusChecked: Checked Received: (qmail 48099 invoked from network); 7 Aug 2017 12:23:10 -0000 Received: from mail-lf0-f66.google.com (HELO mail-lf0-f66.google.com) (209.85.215.66) by server-5.tower-31.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 7 Aug 2017 12:23:10 -0000 Received: by mail-lf0-f66.google.com with SMTP id x16so211514lfb.4 for ; Mon, 07 Aug 2017 05:23:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LFYwnwpcnAtHMaD8S6xEeS5DWFjFyt95VLMDVObaWp0=; b=E+ttvjl9J1axEOTJDphm8zFuI1aPN/omWVQR9WMf6GWCAN6+7wf8xcrftOPRBh1hbZ EDHTc9xC9Old+5Ofdw1OswHvZk0BDahTNOeg119RCLLVErKFXN5hmroI/hc3F4+fmnta V4tuL0+OIZnjHawfY+GXtjzoIzILxjGaAXXLm3B3Uh1qABL67/d0/zC8io2tkxLf3DTz BJMpWAY7aO1bU+FzHd5hVTjJ5EvJgE0QXOT0RAQ1axO/zwVNJWh9HsHXuZnp1Ncr+w8i 6k61yDFQM0C7jCQktehaFUphdLKLuN8MT0JB/0X6TjbF4OvdcX3sM57BtD351niltuPN 5Suw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LFYwnwpcnAtHMaD8S6xEeS5DWFjFyt95VLMDVObaWp0=; b=JggTgodtVHrmvHC1VmOC2c3dFuzqPP7tPF8IMh53Qlqj0D6ES28F1OPe8b1Gtj7bAa tbK1aBJ07eDhqqbznm6uraBBVgTuk+ty2SSxJew65WMLNIXfi0ejNOcNiipiK3Is007n p6yxVZAxE5uwU6RsR/z3k9NVy+I+c2peewBGu8cksruZQVLUQFqNqnRyBQ+li5m/KvI6 yb0jDFUzAP2sr2RUkREHO4S3cEX/0do5p/ZbQgIP3JvlpYzoyl9sPGgsE1d1nZI44FPf bv6ivm23YiXtTyt2BejmX+3KC1ON8JAR2vAtYB30waJMPvzLnT5r7c1PtNp7U0YXRPgi Vcbw== X-Gm-Message-State: AHYfb5jyOdiNN94f+CYE8Ykw1icKtDmTM5NQf+ArAXEUphxW9ETV9PFD KRr+P1+f/BOgoA== X-Received: by 10.46.33.151 with SMTP id h23mr130877lji.66.1502108590204; Mon, 07 Aug 2017 05:23:10 -0700 (PDT) Received: from a2k-HP-ProDesk-600-G2-SFF.kyiv.epam.com (ll-53.209.223.85.sovam.net.ua. [85.223.209.53]) by smtp.gmail.com with ESMTPSA id m143sm1031821lfm.77.2017.08.07.05.23.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 07 Aug 2017 05:23:09 -0700 (PDT) From: Oleksandr Andrushchenko To: alsa-devel@alsa-project.org, xen-devel@lists.xen.org, linux-kernel@vger.kernel.org Date: Mon, 7 Aug 2017 15:22:51 +0300 Message-Id: <1502108577-8099-7-git-send-email-andr2000@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1502108577-8099-1-git-send-email-andr2000@gmail.com> References: <1502108577-8099-1-git-send-email-andr2000@gmail.com> Cc: andr2000@gmail.com, Oleksandr Andrushchenko , tiwai@suse.com, perex@perex.cz Subject: [Xen-devel] [PATCH RESEND1 06/12] ALSA: vsnd: Implement handling of shared buffers X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Oleksandr Andrushchenko Implement shared buffer handling according to the para-virtualized sound device protocol at xen/interface/io/sndif.h: - manage buffer memory - handle granted references - handle page directories Signed-off-by: Oleksandr Andrushchenko --- sound/drivers/xen-front.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c index a92459b2737e..04ebc15757f4 100644 --- a/sound/drivers/xen-front.c +++ b/sound/drivers/xen-front.c @@ -58,6 +58,14 @@ struct xdrv_evtchnl_info { uint16_t resp_id; }; +struct sh_buf_info { + int num_grefs; + grant_ref_t *grefs; + uint8_t *vdirectory; + uint8_t *vbuffer; + size_t vbuffer_sz; +}; + struct cfg_stream { int unique_id; char *xenstore_path; @@ -825,6 +833,176 @@ static void xdrv_remove_internal(struct xdrv_info *drv_info) xdrv_evtchnl_free_all(drv_info); } +static inline grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf) +{ + if (!buf->grefs) + return GRANT_INVALID_REF; + return buf->grefs[0]; +} + +static inline void sh_buf_clear(struct sh_buf_info *buf) +{ + memset(buf, 0, sizeof(*buf)); +} + +static void sh_buf_free(struct sh_buf_info *buf) +{ + int i; + + if (buf->grefs) { + for (i = 0; i < buf->num_grefs; i++) + if (buf->grefs[i] != GRANT_INVALID_REF) + gnttab_end_foreign_access(buf->grefs[i], + 0, 0UL); + kfree(buf->grefs); + } + kfree(buf->vdirectory); + free_pages_exact(buf->vbuffer, buf->vbuffer_sz); + sh_buf_clear(buf); +} + +/* + * number of grant references a page can hold with respect to the + * xendispl_page_directory header + */ +#define XENSND_NUM_GREFS_PER_PAGE ((XEN_PAGE_SIZE - \ + offsetof(struct xensnd_page_directory, gref)) / \ + sizeof(grant_ref_t)) + +static void sh_buf_fill_page_dir(struct sh_buf_info *buf, int num_pages_dir) +{ + struct xensnd_page_directory *page_dir; + unsigned char *ptr; + int i, cur_gref, grefs_left, to_copy; + + ptr = buf->vdirectory; + grefs_left = buf->num_grefs - num_pages_dir; + /* + * skip grant references at the beginning, they are for pages granted + * for the page directory itself + */ + cur_gref = num_pages_dir; + for (i = 0; i < num_pages_dir; i++) { + page_dir = (struct xensnd_page_directory *)ptr; + if (grefs_left <= XENSND_NUM_GREFS_PER_PAGE) { + to_copy = grefs_left; + page_dir->gref_dir_next_page = GRANT_INVALID_REF; + } else { + to_copy = XENSND_NUM_GREFS_PER_PAGE; + page_dir->gref_dir_next_page = buf->grefs[i + 1]; + } + memcpy(&page_dir->gref, &buf->grefs[cur_gref], + to_copy * sizeof(grant_ref_t)); + ptr += XEN_PAGE_SIZE; + grefs_left -= to_copy; + cur_gref += to_copy; + } +} + +static int sh_buf_grant_refs(struct xenbus_device *xb_dev, + struct sh_buf_info *buf, + int num_pages_dir, int num_pages_vbuffer, int num_grefs) +{ + grant_ref_t priv_gref_head; + int ret, i, j, cur_ref; + int otherend_id; + + ret = gnttab_alloc_grant_references(num_grefs, &priv_gref_head); + if (ret) + return ret; + + buf->num_grefs = num_grefs; + otherend_id = xb_dev->otherend_id; + j = 0; + + for (i = 0; i < num_pages_dir; i++) { + cur_ref = gnttab_claim_grant_reference(&priv_gref_head); + if (cur_ref < 0) { + ret = cur_ref; + goto fail; + } + + gnttab_grant_foreign_access_ref(cur_ref, otherend_id, + xen_page_to_gfn(virt_to_page(buf->vdirectory + + XEN_PAGE_SIZE * i)), 0); + buf->grefs[j++] = cur_ref; + } + + for (i = 0; i < num_pages_vbuffer; i++) { + cur_ref = gnttab_claim_grant_reference(&priv_gref_head); + if (cur_ref < 0) { + ret = cur_ref; + goto fail; + } + + gnttab_grant_foreign_access_ref(cur_ref, otherend_id, + xen_page_to_gfn(virt_to_page(buf->vbuffer + + XEN_PAGE_SIZE * i)), 0); + buf->grefs[j++] = cur_ref; + } + + gnttab_free_grant_references(priv_gref_head); + sh_buf_fill_page_dir(buf, num_pages_dir); + return 0; + +fail: + gnttab_free_grant_references(priv_gref_head); + return ret; +} + +static int sh_buf_alloc_int_buffers(struct sh_buf_info *buf, + int num_pages_dir, int num_pages_vbuffer, int num_grefs) +{ + buf->grefs = kcalloc(num_grefs, sizeof(*buf->grefs), GFP_KERNEL); + if (!buf->grefs) + return -ENOMEM; + + buf->vdirectory = kcalloc(num_pages_dir, XEN_PAGE_SIZE, GFP_KERNEL); + if (!buf->vdirectory) + goto fail; + + buf->vbuffer_sz = num_pages_vbuffer * XEN_PAGE_SIZE; + buf->vbuffer = alloc_pages_exact(buf->vbuffer_sz, GFP_KERNEL); + if (!buf->vbuffer) + goto fail; + return 0; + +fail: + kfree(buf->grefs); + buf->grefs = NULL; + kfree(buf->vdirectory); + buf->vdirectory = NULL; + return -ENOMEM; +} + +static int sh_buf_alloc(struct xenbus_device *xb_dev, + struct sh_buf_info *buf, unsigned int buffer_size) +{ + int num_pages_vbuffer, num_pages_dir, num_grefs; + int ret; + + sh_buf_clear(buf); + + num_pages_vbuffer = DIV_ROUND_UP(buffer_size, XEN_PAGE_SIZE); + /* number of pages the page directory consumes itself */ + num_pages_dir = DIV_ROUND_UP(num_pages_vbuffer, + XENSND_NUM_GREFS_PER_PAGE); + num_grefs = num_pages_vbuffer + num_pages_dir; + + ret = sh_buf_alloc_int_buffers(buf, num_pages_dir, + num_pages_vbuffer, num_grefs); + if (ret < 0) + return ret; + + ret = sh_buf_grant_refs(xb_dev, buf, + num_pages_dir, num_pages_vbuffer, num_grefs); + if (ret < 0) + return ret; + + sh_buf_fill_page_dir(buf, num_pages_dir); + return 0; +} + static int xdrv_be_on_initwait(struct xdrv_info *drv_info) { int stream_idx;