From patchwork Tue Aug 15 21:31:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Zhi A" X-Patchwork-Id: 9901897 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 3018B60244 for ; Tue, 15 Aug 2017 13:32:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2306B287EC for ; Tue, 15 Aug 2017 13:32:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 17EF8287F2; Tue, 15 Aug 2017 13:32:36 +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=-2.3 required=2.0 tests=BAYES_00, DATE_IN_FUTURE_06_12, RCVD_IN_DNSWL_MED 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 B0A4C287F0 for ; Tue, 15 Aug 2017 13:32:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 483D56E2BC; Tue, 15 Aug 2017 13:32:35 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTPS id ADC136E2B5; Tue, 15 Aug 2017 13:32:31 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Aug 2017 06:32:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,377,1498546800"; d="scan'208";a="300352127" Received: from zhiwang1-mobl.bj.intel.com ([10.238.154.56]) by fmsmga004.fm.intel.com with ESMTP; 15 Aug 2017 06:32:29 -0700 From: Zhi Wang To: intel-gfx@lists.freedesktop.org, intel-gvt-dev@lists.freedesktop.org Date: Wed, 16 Aug 2017 05:31:12 +0800 Message-Id: <1502832675-6123-5-git-send-email-zhi.a.wang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1502832675-6123-1-git-send-email-zhi.a.wang@intel.com> References: <1502832675-6123-1-git-send-email-zhi.a.wang@intel.com> Subject: [Intel-gfx] [RFC 4/7] drm/i915: Introduce dynamic private PAT management 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 To manage the dynamic private PAT entries, this patch introduces some basic functionalities for getting and putting an expected private PAT entry. When building the private PAT mapping between virtual PPAT indexes and physical PPAT indexes, GVT-g would check if there is already an usable private PAT entry. If it's a perfect match, it would be directly used. If it's not a perfect match and there is still unused PPAT entry, GVT will allocate a new PPAT entry index for a guest. If it's not a perfect match and there is no available unused PPAT entry, GVT will use the parital matched PPAT entry index. Each dynamic PPAT entry is associated with a reference count. If no vGPU is using it, it will be freed. Signed-off-by: Zhi Wang --- drivers/gpu/drm/i915/gvt/gtt.c | 100 +++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/gtt.h | 6 +++ 2 files changed, 106 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index c630015..6e19d7a 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -2254,6 +2254,103 @@ static int setup_spt_oos(struct intel_gvt *gvt) return ret; } +static void setup_private_pat(struct intel_gvt *gvt) +{ + struct drm_i915_private *dev_priv = gvt->dev_priv; + struct intel_gvt_gtt *gtt = &gvt->gtt; + struct intel_gvt_gtt_pat_ops *ops = gtt->pat_ops; + int i; + + i = find_first_bit(dev_priv->avail_ppat_bitmap, gtt->max_ppat_index); + if (i >= gtt->max_ppat_index) { + DRM_DEBUG_DRIVER("no private PAT support\n"); + return; + } + + gtt->has_ppat = true; + + /* Save available PPAT bitmap from host */ + bitmap_copy(gtt->avail_ppat_bitmap, dev_priv->avail_ppat_bitmap, + gtt->max_ppat_index); + + /* Read host PPAT configuration */ + for_each_clear_bit(i, gtt->avail_ppat_bitmap, gtt->max_ppat_index) + gtt->ppat_value[i] = ops->get_pat_value(NULL, i, gvt); +} + +static int get_private_pat_index(struct intel_gvt *gvt, u32 value) +{ + struct drm_i915_private *dev_priv = gvt->dev_priv; + struct intel_gvt_gtt *gtt = &gvt->gtt; + struct intel_gvt_gtt_pat_ops *ops = gtt->pat_ops; + int i, index, used; + unsigned int score, best_score; + + if (WARN_ON(!gtt->has_ppat)) + return 0; + + score = best_score = 0; + used = 0; + + /* First, find a suitable value from available configurations */ + for_each_clear_bit(i, gtt->avail_ppat_bitmap, gtt->max_ppat_index) { + score = ops->match_pat_value(gtt->ppat_value[i], value); + /* Perfect match */ + if (score == ~0) { + index = i; + goto found; + } + + if (score > best_score) { + index = i; + best_score = score; + } + used++; + } + + if (!best_score && used == gtt->max_ppat_index) { + DRM_ERROR("cannot find a suitable PPAT entry\n"); + return -ENOSPC; + } + + /* + * Found a matched entry which is not perfect, + * but we don't have a available free entry + */ + if (best_score && used == gtt->max_ppat_index) + goto found; + + /* Allocate a new one */ + index = find_first_bit(gtt->avail_ppat_bitmap, gtt->max_ppat_index); + clear_bit(index, gtt->avail_ppat_bitmap); + gtt->ppat_value[index] = value; + ops->set_pat_value(NULL, index, gtt->ppat_value[index], gvt); + +found: + /* Not need to increase reference for host entries.*/ + if (test_bit(index, dev_priv->avail_ppat_bitmap)) + return index; + + atomic_inc(>t->ppat_refc[index]); + return index; +} + +static void put_private_pat_index(struct intel_gvt *gvt, unsigned int index) +{ + struct drm_i915_private *dev_priv = gvt->dev_priv; + struct intel_gvt_gtt *gtt = &gvt->gtt; + + if (WARN_ON(!gtt->has_ppat)) + return; + + /* Nothing to do with host PPAT configuration */ + if (test_bit(index, dev_priv->avail_ppat_bitmap)) + return; + + if (atomic_dec_and_test(>t->ppat_refc[index])) + set_bit(index, gtt->avail_ppat_bitmap); +} + /** * intel_vgpu_find_ppgtt_mm - find a PPGTT mm object * @vgpu: a vGPU @@ -2386,12 +2483,15 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt) gvt->gtt.pte_ops = &gen8_gtt_pte_ops; gvt->gtt.gma_ops = &gen8_gtt_gma_ops; gvt->gtt.pat_ops = &gen8_pat_ops; + gvt->gtt.max_ppat_index = 8; gvt->gtt.mm_alloc_page_table = gen8_mm_alloc_page_table; gvt->gtt.mm_free_page_table = gen8_mm_free_page_table; } else { return -ENODEV; } + setup_private_pat(gvt); + page = (void *)get_zeroed_page(GFP_KERNEL); if (!page) { gvt_err("fail to allocate scratch ggtt page\n"); diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index 02f6bd9..6cd4fc7 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h @@ -100,6 +100,12 @@ struct intel_gvt_gtt { struct page *scratch_ggtt_page; unsigned long scratch_ggtt_mfn; + + DECLARE_BITMAP(avail_ppat_bitmap, MAX_PPAT_INDEX); + unsigned int ppat_value[MAX_PPAT_INDEX]; + atomic_t ppat_refc[MAX_PPAT_INDEX]; + unsigned int max_ppat_index; + bool has_ppat; }; enum {