From patchwork Mon Aug 7 11:50:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Andrushchenko X-Patchwork-Id: 9885157 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 7E5F360363 for ; Mon, 7 Aug 2017 11:53:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6FB582860D for ; Mon, 7 Aug 2017 11:53:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 643D428621; Mon, 7 Aug 2017 11:53: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 BAE5A2860D for ; Mon, 7 Aug 2017 11:53: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 1degYp-0003yy-N7; Mon, 07 Aug 2017 11:51:03 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1degYn-0003xs-TW for xen-devel@lists.xen.org; Mon, 07 Aug 2017 11:51:02 +0000 Received: from [85.158.137.68] by server-13.bemta-3.messagelabs.com id 37/FC-01862-52458895; Mon, 07 Aug 2017 11:51:01 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrIIsWRWlGSWpSXmKPExsVyMfS6s65KSEe kwcxbohZLPi5mcWD0OLr7N1MAYxRrZl5SfkUCa8a3fX1MBe3aFXNv3mRtYHyj0sXIxSEk0M8o cWjRXzYQh0XgJYvEqS1HmUEcCYF+VonTF44zdjFyAjlxEnPn7maBsMskGv9eYAOxhQQUJb4+m 84EYa9kkrjcqQNiswkYSSy/8QOsXkQgQuLY4w9g9cwCpRI39s9hBrGFBfwkbq4/AFbDIqAq8f d6K5jNK+AocXfDMVaIXXISN891AtVzcHAKOEm0Lq2AWAVUsns2+wRGgQWMDKsYNYpTi8pSi3S NTPSSijLTM0pyEzNzdA0NjPVyU4uLE9NTcxKTivWS83M3MQIDq56BgXEH46vjfocYJTmYlER5 41e0RQrxJeWnVGYkFmfEF5XmpBYfYpTh4FCS4N0f1BEpJFiUmp5akZaZAwxxmLQEB4+SCG82S Jq3uCAxtzgzHSJ1itGe48qVdV+YODasXg8kpxzYDiRfTfj/jUmIJS8/L1VKnJc1GKhNAKQtoz QPbigsJi8xykoJ8zIyMDAI8RSkFuVmlqDKv2IU52BUEuZ9ALKcJzOvBG73K6CzmIDOepPYCnJ WSSJCSqqBsfVkKnuW0lt7vllrviydbqGft7zkmpjjcuGNqdYGgdnvGH9eNDMz4Iu4y7huvoA6 75FKP78J19Rk/6QJrdP4WHLh8tUrf6cbr77fVWyjor3lH2eDwK3vjYz29nmnTv+uMshY8rC3d fc3HXsps4YW80tpHHVJ25nOc6ht2ZSYvchM0jVFjEdViaU4I9FQi7moOBEATVWJcMQCAAA= X-Env-Sender: andr2000@gmail.com X-Msg-Ref: server-2.tower-31.messagelabs.com!1502106659!97222444!1 X-Originating-IP: [209.85.215.67] 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 14373 invoked from network); 7 Aug 2017 11:51:00 -0000 Received: from mail-lf0-f67.google.com (HELO mail-lf0-f67.google.com) (209.85.215.67) by server-2.tower-31.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 7 Aug 2017 11:51:00 -0000 Received: by mail-lf0-f67.google.com with SMTP id y15so148314lfd.5 for ; Mon, 07 Aug 2017 04:51:00 -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=CJataZWkqm7YDUeo2y1fLUXINaQv2iN0VMcGu1I/8TKqTXHvCskEOIxzeMseldhG6p v4aQjNTxRs26yMYaGW+dN22EK2nPOfrycRMoadrXEnddGWsDBCSh86e+eiyMvUQDnz+M p12JIWiHlHbakjrMHH1XYeIRBWah4XgJloz0FKFJTFBuWRcbr+g63hU4yi2waKUjiFJr 3msf1bVWzOdPt6rABlrrdstn+fcIOCmATCWWCs5iGBj2yu4YCVgdINPphnpqMVHfNP34 u7/0uO5sSDVRWFg9hcNUTuMbThsPSpcuxk9Mb61G2rpI0E/dzdkMG3Dx2i11RhxgDBff Lg+A== 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=HRu7IXBI3Bo0TKbGyDzismaiqCymB4wFSPA+dZ1s3VGZUdyhC1OJ/YUSeglq8P5Fqy 1/un+HXuxDTn5Hvxs6Kg1VmRrNWdvwuR1IPaCxS9kF77N5r9Jqeh5fBca0YVRljAWLkm 1XQBihdRAwTiDmHL5AKWEg9n9Qy55DiRBPfMqC/U16DeJ4PsLcT2Rck+nxi3FRl+Sq7T cS6IikqrgR78uiTx41N4ES9F13KIdEeuFGr9fzdYW9w+KtdGZJ4ICl8iZ630B3gfnNST JY1nlJmPC6UoHbJJm7siq6eoZyxK58JANZHxm303vh/U8vjZk2BTvF3ayLo7Lx863NJO zo2w== X-Gm-Message-State: AHYfb5iwdiDo01VyBHNasLJNXKCrI979Lbsoh2zBZB0kvlauTYkZkTDz +MSvj9nqm6jfwA== X-Received: by 10.46.9.202 with SMTP id 193mr79941ljj.137.1502106659727; Mon, 07 Aug 2017 04:50:59 -0700 (PDT) Received: from a2k-HP-ProDesk-600-G2-SFF.kyiv.epam.com (ll-51.209.223.85.sovam.net.ua. [85.223.209.51]) by smtp.gmail.com with ESMTPSA id n88sm2844587lja.43.2017.08.07.04.50.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 07 Aug 2017 04:50:58 -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 14:50:39 +0300 Message-Id: <1502106645-6731-6-git-send-email-andr2000@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1502106645-6731-1-git-send-email-andr2000@gmail.com> References: <1502106645-6731-1-git-send-email-andr2000@gmail.com> Cc: andr2000@gmail.com, Oleksandr Andrushchenko , tiwai@suse.com, perex@perex.cz Subject: [Xen-devel] [PATCH RESEND 05/11] 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;