From patchwork Thu Oct 13 09:03:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 9374575 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 C607060839 for ; Thu, 13 Oct 2016 09:04:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B4DA029E6B for ; Thu, 13 Oct 2016 09:04:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A936329E7C; Thu, 13 Oct 2016 09:04:24 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2C3CB29E6B for ; Thu, 13 Oct 2016 09:04:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3BCAA6E9CC; Thu, 13 Oct 2016 09:04:21 +0000 (UTC) X-Original-To: Intel-gfx@lists.freedesktop.org Delivered-To: Intel-gfx@lists.freedesktop.org Received: from mail-lf0-x243.google.com (mail-lf0-x243.google.com [IPv6:2a00:1450:4010:c07::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id E24B16E9C4 for ; Thu, 13 Oct 2016 09:04:17 +0000 (UTC) Received: by mail-lf0-x243.google.com with SMTP id x79so11606400lff.2 for ; Thu, 13 Oct 2016 02:04:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ursulin-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=aBL5bZqepVY/BYWM70y1hPcT20p5fFM1gq6ZE6HSKG4=; b=Q+lxd7NkXudKxM3j8lvh3iEGNt8xpKGuACNHotF+XQP/kqjZLHB2BCux7OrybAUM/I cqJf6I79AtTeMdLqbpxe6u2dmJ5tYi4+lNxnQ7jXKlF9qya1Ydm0NZIL33XQs6+jTDOz JLMsuRHuLcRVoCaHAbqf7ey7VWYDadVAp+7vOLDO2qFQyei2fBihNjxCPSaVu6erWfii 0xm3s0vCqhFXC2S+yGrcqtA7N/PQohTJ68looFiEeTcBpiDNa8H0rbavkYOOb/53Fkvx QbGMZ81QIvQkcgxCMFdVg/nPrKJ9V10FkEul77rXUGKsnHsfKWU5s9qquiAjespzlyQj I30w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=aBL5bZqepVY/BYWM70y1hPcT20p5fFM1gq6ZE6HSKG4=; b=PWu4c3W549hlBkStZIwWiUIkwl2RMsNf1SAq12xmv3oZKOo+WeBVWYZGoIdqOVt3dW YY0xW8+CkSEf3VANNzYrYfcrY1EHxiUXjeEltRH5Rh9PRA9VfevEfIcoxzQDIopC1m3m kgnTh7ALcPzV+pngdd/rT17aYurvQeniMJGrpBZYqNR+kqVFCAIQHvpoUGSpLnBHMDIw cVphtkwPd4vG0zpFk7lvGX0pAGBUPhG/aF4OQgShI1hM9wCvVDe2+Mlh0JkZCqLb4h92 mX0MXqIis30x1nnPZK1CyhCPOOpBNHxAHTT8U1amcM17GAIxea9eVATOohP6zBMIg4I2 TGCQ== X-Gm-Message-State: AA6/9Rk4WBAWbFbJGRwhK5mFOYKJOpf0Ov/aAB5QYizWZmcaakjevPbXrAQgLXKBM5P44w== X-Received: by 10.194.205.1 with SMTP id lc1mr1941587wjc.192.1476349455869; Thu, 13 Oct 2016 02:04:15 -0700 (PDT) Received: from localhost.localdomain ([2a02:c7d:9b6d:e300:916a:6cab:ac67:71c2]) by smtp.gmail.com with ESMTPSA id y2sm20776894wjx.20.2016.10.13.02.04.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Oct 2016 02:04:15 -0700 (PDT) From: Tvrtko Ursulin X-Google-Original-From: Tvrtko Ursulin To: Intel-gfx@lists.freedesktop.org Date: Thu, 13 Oct 2016 10:03:59 +0100 Message-Id: <1476349444-7331-3-git-send-email-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476349444-7331-1-git-send-email-tvrtko.ursulin@linux.intel.com> References: <1476349444-7331-1-git-send-email-tvrtko.ursulin@linux.intel.com> Subject: [Intel-gfx] [RFC 2/7] drm/i915: Use i915_sg_create for userptr X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Tvrtko Ursulin Now that we have a helper which builds the sg lists, use it from the userptr code as well. To do this we first export the API and add kerneldoc for it. Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_drv.h | 33 +++++++++++++++++ drivers/gpu/drm/i915/i915_gem.c | 65 +++++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_userptr.c | 51 +++++--------------------- 3 files changed, 87 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bf397b643cc0..e226794ffc1b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3999,4 +3999,37 @@ int remap_io_mapping(struct vm_area_struct *vma, __T; \ }) +/** + * struct i915_sg_create_state - state object for the sg creation helpers + * @st: sg_table being created + * @sg: Current scatterlist entry iterated over + * @idx: Current page index iterated over + * @page_count: Number of pages requested for the sg table to hold at creation + * @max_segment: Maximum size in bytes of a single sg entry + * @last_pfn: Page frame number of the previously added page + */ +struct i915_sg_create_state { + struct sg_table *st; + struct scatterlist *sg; + unsigned int idx; + unsigned int page_count; + unsigned long max_segment; + unsigned long last_pfn; +}; + +struct i915_sg_create_state *i915_sg_create(unsigned int page_count); +void i915_sg_add_page(struct i915_sg_create_state *state, struct page *page); +struct sg_table *i915_sg_complete(struct i915_sg_create_state *state); +void i915_sg_abort(struct i915_sg_create_state *state); + +/** + * i915_sg_for_each_page - sg creation iterator + * @state: state object created by i915_sg_create + * + * Iterates page_count times over the created state allowing the caller to + * call i915_sg_add_page for all the pages it wants to build the list from. + */ +#define i915_sg_for_each_page(state) \ + for( ; (state)->idx < (state)->page_count; ) + #endif diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 93b047735e6b..1c1aa3bbde8a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2216,17 +2216,16 @@ static unsigned long swiotlb_max_size(void) #endif } -struct i915_sg_create_state { - struct sg_table *st; - struct scatterlist *sg; - unsigned int idx; - unsigned int page_count; - unsigned long max_segment; - unsigned long last_pfn; -}; - -static struct i915_sg_create_state * -i915_sg_create(unsigned int page_count) +/** + * i915_sg_create - creates the state object for sg list building + * @page_count: number of pages the caller intends to add to the list + * + * This function creates a state object which is to be used with the + * accompanying family of functions used to build the scatter-gather list. + * + * Returns a pointer to the state structure or ERR_PTR otherwise. + */ +struct i915_sg_create_state *i915_sg_create(unsigned int page_count) { struct i915_sg_create_state *state; struct sg_table *st; @@ -2260,8 +2259,17 @@ i915_sg_create(unsigned int page_count) return state; } -static void -i915_sg_add_page(struct i915_sg_create_state *state, struct page *page) +/** + * i915_sg_add_page - adds a page to the sg list being built + * @state: state created with i915_sg_create + * @page: struct page pointer of the page to add to the list + * + * Intended to be called under the i915_sg_for_each_page iterator once for each + * page which needs to be added to the sg list. + * Function manages the internal state which can be read (only!) by the caller + * where appropriate. + */ +void i915_sg_add_page(struct i915_sg_create_state *state, struct page *page) { unsigned long pfn = page_to_pfn(page); struct scatterlist *sg = state->sg; @@ -2282,8 +2290,17 @@ i915_sg_add_page(struct i915_sg_create_state *state, struct page *page) state->idx++; } -static struct sg_table * -i915_sg_complete(struct i915_sg_create_state *state) +/** + * i915_sg_complete - completes the sg list building + * @state: state created with i915_sg_create + * + * When all the pages have been successsfuly added to the sg list, this function + * is called to retrieve the fully build sg_table pointer. + * State object is not valid after this is called. + * + * Returns the sg_table pointer ready to be used. + */ +struct sg_table *i915_sg_complete(struct i915_sg_create_state *state) { struct sg_table *st = state->st; @@ -2295,17 +2312,25 @@ i915_sg_complete(struct i915_sg_create_state *state) return st; } -static void -i915_sg_abort(struct i915_sg_create_state *state) +/** + * i915_sg_abort - aborts the sg list building + * @state: state previously created with i915_sg_create + * + * In cases when something goes wrong with the sg list building, callers need + * to call this function to cleanup the objects and state allocated by the + * i915_sg_create. + * State object must not be accessed after calling this. + * Callers are responsible to do the correct thing with regards to individual + * page freeing/releasing themselves, but this helper will free the sg table + * and scatter gather entries. + */ +void i915_sg_abort(struct i915_sg_create_state *state) { sg_free_table(state->st); kfree(state->st); kfree(state); } -#define i915_sg_for_each_page(state) \ - for( ; (state)->idx < (state)->page_count; ) - static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) { diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index e537930c64b5..ced19610d911 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -397,54 +397,21 @@ struct get_pages_work { struct task_struct *task; }; -#if IS_ENABLED(CONFIG_SWIOTLB) -#define swiotlb_active() swiotlb_nr_tbl() -#else -#define swiotlb_active() 0 -#endif - -static int -st_set_pages(struct sg_table **st, struct page **pvec, int num_pages) -{ - struct scatterlist *sg; - int ret, n; - - *st = kmalloc(sizeof(**st), GFP_KERNEL); - if (*st == NULL) - return -ENOMEM; - - if (swiotlb_active()) { - ret = sg_alloc_table(*st, num_pages, GFP_KERNEL); - if (ret) - goto err; - - for_each_sg((*st)->sgl, sg, num_pages, n) - sg_set_page(sg, pvec[n], PAGE_SIZE, 0); - } else { - ret = sg_alloc_table_from_pages(*st, pvec, num_pages, - 0, num_pages << PAGE_SHIFT, - GFP_KERNEL); - if (ret) - goto err; - } - - return 0; - -err: - kfree(*st); - *st = NULL; - return ret; -} - static int __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj, struct page **pvec, int num_pages) { + struct i915_sg_create_state *state; int ret; - ret = st_set_pages(&obj->pages, pvec, num_pages); - if (ret) - return ret; + state = i915_sg_create(num_pages); + if (IS_ERR(state)) + return PTR_ERR(state); + + i915_sg_for_each_page(state) + i915_sg_add_page(state, pvec[state->idx]); + + obj->pages = i915_sg_complete(state); ret = i915_gem_gtt_prepare_object(obj); if (ret) {