From: "Yu, Zhang" <yu.c.zhang@linux.intel.com>
To: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>,
Intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v3 2/8] drm/i915: Adds graphic address space ballooning logic
Date: Tue, 16 Dec 2014 21:22:01 +0800 [thread overview]
Message-ID: <549031F9.8000108@linux.intel.com> (raw)
In-Reply-To: <548AE6EA.4000200@linux.intel.com>
On 12/12/2014 9:00 PM, Tvrtko Ursulin wrote:
>
> On 11/13/2014 12:02 PM, Yu Zhang wrote:
>> With Intel GVT-g, the global graphic memory space is partitioned by
>> multiple vGPU instances in different VMs. The ballooning code is called
>> in i915_gem_setup_global_gtt(), utilizing the drm mm allocator APIs to
>> mark the graphic address space which are partitioned out to other vGPUs
>> as reserved.
>>
>> v2:
>> take Chris and Daniel's comments:
>> - no guard page between different VMs
>> - use drm_mm_reserve_node() to do the reservation for ballooning,
>> instead of the previous drm_mm_insert_node_in_range_generic()
>>
>> v3:
>> take Daniel's comments:
>> - move ballooning functions into i915_vgpu.c
>> - add kerneldoc to ballooning functions
>>
>> Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com>
>> Signed-off-by: Jike Song <jike.song@intel.com>
>> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
>> Signed-off-by: Eddie Dong <eddie.dong@intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_gem_gtt.c | 17 +++-
>> drivers/gpu/drm/i915/i915_vgpu.c | 149
>> ++++++++++++++++++++++++++++++++++++
>> drivers/gpu/drm/i915/i915_vgpu.h | 2 +
>> 3 files changed, 165 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c
>> b/drivers/gpu/drm/i915/i915_gem_gtt.c
>> index de12017..2dfac13 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
>> @@ -27,6 +27,7 @@
>> #include <drm/drmP.h>
>> #include <drm/i915_drm.h>
>> #include "i915_drv.h"
>> +#include "i915_vgpu.h"
>> #include "i915_trace.h"
>> #include "intel_drv.h"
>>
>> @@ -1683,6 +1684,16 @@ int i915_gem_setup_global_gtt(struct drm_device
>> *dev,
>>
>> /* Subtract the guard page ... */
>> drm_mm_init(&ggtt_vm->mm, start, end - start - PAGE_SIZE);
>> +
>> + dev_priv->gtt.base.start = start;
>> + dev_priv->gtt.base.total = end - start;
>> +
>> + if (intel_vgpu_active(dev)) {
>> + ret = intel_vgt_balloon(dev);
>> + if (ret)
>> + return ret;
>> + }
>> +
>
> Out of curiosity, what will be the mechanism to prevent a vGPU instance
> from ignoring the ballooning data? Must be something in the hypervisor
> blocking pass-through access to such domains?
Well, although we have range check logic in the host side(which checks
the legality of a GM address), the correctness of a GM from vGPU side
are supposed to be guaranteed by the drm mm allocator - all those
ballooned out spaces are marked as reserved.
>
> And probably GPU reset should also be disallowed for vGPU instances?
>
>> if (!HAS_LLC(dev))
>> dev_priv->gtt.base.mm.color_adjust = i915_gtt_color_adjust;
>>
>> @@ -1702,9 +1713,6 @@ int i915_gem_setup_global_gtt(struct drm_device
>> *dev,
>> vma->bound |= GLOBAL_BIND;
>> }
>>
>> - dev_priv->gtt.base.start = start;
>> - dev_priv->gtt.base.total = end - start;
>> -
>> /* Clear any non-preallocated blocks */
>> drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) {
>> DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
>> @@ -1756,6 +1764,9 @@ void i915_global_gtt_cleanup(struct drm_device
>> *dev)
>> }
>>
>> if (drm_mm_initialized(&vm->mm)) {
>> + if (intel_vgpu_active(dev))
>> + intel_vgt_deballoon();
>> +
>> drm_mm_takedown(&vm->mm);
>> list_del(&vm->global_link);
>> }
>> diff --git a/drivers/gpu/drm/i915/i915_vgpu.c
>> b/drivers/gpu/drm/i915/i915_vgpu.c
>> index 3f6b797..ff5fba3 100644
>> --- a/drivers/gpu/drm/i915/i915_vgpu.c
>> +++ b/drivers/gpu/drm/i915/i915_vgpu.c
>> @@ -83,3 +83,152 @@ void i915_check_vgpu(struct drm_device *dev)
>> dev_priv->vgpu.active = true;
>> DRM_INFO("Virtual GPU for Intel GVT-g detected.\n");
>> }
>> +
>> +struct _balloon_info_ {
>> + /*
>> + * There are up to 2 regions per low/high graphic memory that
>> + * might be ballooned. Here, index 0/1 is for low
>> + * graphic memory, 2/3 for high graphic memory.
>> + */
>> + struct drm_mm_node space[4];
>> +} bl_info;
>
> This should be static I think.
Yes, you are right.
>
>> +/**
>> + * intel_vgt_deballoon - deballoon reserved graphics address trunks
>> + *
>> + * This function is called to deallocate the ballooned-out graphic
>> memory, when
>> + * driver is unloaded or when ballooning fails.
>> + */
>> +void intel_vgt_deballoon(void)
>> +{
>> + int i;
>> +
>> + DRM_INFO("VGT deballoon.\n");
>
> Would debug be more appropriate? I don't see much value of saying this
> on driver unload - it's not that it is optional at this point.
OK. :)
>
> Also for all logging, is intended human readable name VGT or vGT? If the
> latter it would be nicer to log it in that form.
Well, I prefer VGT. :)
>
>> +
>> + for (i = 0; i < 4; i++) {
>> + if (bl_info.space[i].allocated)
>> + drm_mm_remove_node(&bl_info.space[i]);
>> + }
>> +
>> + memset(&bl_info, 0, sizeof(bl_info));
>> +}
>> +
>> +static int vgt_balloon_space(struct drm_mm *mm,
>> + struct drm_mm_node *node,
>> + unsigned long start, unsigned long end)
>> +{
>> + unsigned long size = end - start;
>> +
>> + if (start == end)
>> + return -EINVAL;
>> +
>> + DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KB.\n",
>> + start, end, size / 1024);
>
> KiB ?
Yes. Thanks. :)
>
>> + node->start = start;
>> + node->size = size;
>> +
>> + return drm_mm_reserve_node(mm, node);
>> +}
>> +
>> +/**
>> + * intel_vgt_balloon - balloon out reserved graphics address trunks
>> + * @dev: drm device
>> + *
>> + * This function is called at the initialization stage, to balloon
>> out the
>> + * graphic address space allocated to other VMs, by marking these
>> spaces as
>> + * reserved.
>> + *
>> + * The ballooning related knowledges(starting address and size of the
>> low/high
>
> s/knowledges\(/knowledge /
Got it.
>
>> + * graphic memory) are depicted in the vgt_if structure in a reserved
>> MMIO
>> + * range.
>> + *
>> + * Returns:
>> + * zero on success, non-zero if configuration invalid or ballooning
>> failed
>> + */
>> +int intel_vgt_balloon(struct drm_device *dev)
>> +{
>> + struct drm_i915_private *dev_priv = to_i915(dev);
>> + struct i915_address_space *ggtt_vm = &dev_priv->gtt.base;
>> + unsigned long ggtt_vm_end = ggtt_vm->start + ggtt_vm->total;
>> +
>> + unsigned long low_gm_base, low_gm_size, low_gm_end;
>> + unsigned long high_gm_base, high_gm_size, high_gm_end;
>> + int ret;
>> +
>> + low_gm_base = I915_READ(vgtif_reg(avail_rs.low_gmadr.my_base));
>> + low_gm_size = I915_READ(vgtif_reg(avail_rs.low_gmadr.my_size));
>> + high_gm_base = I915_READ(vgtif_reg(avail_rs.high_gmadr.my_base));
>> + high_gm_size = I915_READ(vgtif_reg(avail_rs.high_gmadr.my_size));
>
> Get rid of my_ prefix ?
OK. Will do. :)
>
>> +
>> + low_gm_end = low_gm_base + low_gm_size;
>> + high_gm_end = high_gm_base + high_gm_size;
>> +
>> + DRM_INFO("VGT ballooning configuration:\n");
>> + DRM_INFO("Low graphic memory: base 0x%lx size %ldKB\n",
>> + low_gm_base, low_gm_size / 1024);
>> + DRM_INFO("High graphic memory: base 0x%lx size %ldKB\n",
>> + high_gm_base, high_gm_size / 1024);
>> +
>> + if (low_gm_base < ggtt_vm->start
>> + || low_gm_end > dev_priv->gtt.mappable_end
>> + || high_gm_base < dev_priv->gtt.mappable_end
>> + || high_gm_end > ggtt_vm_end) {
>> + DRM_ERROR("Invalid ballooning configuration!\n");
>> + return -EINVAL;
>> + }
>> +
>> + memset(&bl_info, 0, sizeof(bl_info));
>
> If bl_info is static then you don't need this memset?
Oh, yes. :)
>
>> + /* High graphic memory ballooning */
>> + if (high_gm_base > dev_priv->gtt.mappable_end) {
>> + ret = vgt_balloon_space(&ggtt_vm->mm,
>> + &bl_info.space[2],
>> + dev_priv->gtt.mappable_end,
>> + high_gm_base);
>> +
>> + if (ret)
>> + goto err;
>> + }
>> +
>> + /*
>> + * No need to partition out the last physical page,
>> + * because it is reserved to the guard page.
>> + */
>> + if (high_gm_end < ggtt_vm_end - PAGE_SIZE) {
>> + ret = vgt_balloon_space(&ggtt_vm->mm,
>> + &bl_info.space[3],
>> + high_gm_end,
>> + ggtt_vm_end - PAGE_SIZE);
>> + if (ret)
>> + goto err;
>> + }
>> +
>> + /* Low graphic memory ballooning */
>> + if (low_gm_base > ggtt_vm->start) {
>> + ret = vgt_balloon_space(&ggtt_vm->mm,
>> + &bl_info.space[0],
>> + ggtt_vm->start, low_gm_base);
>> +
>> + if (ret)
>> + goto err;
>> + }
>> +
>> + if (low_gm_end < dev_priv->gtt.mappable_end) {
>> + ret = vgt_balloon_space(&ggtt_vm->mm,
>> + &bl_info.space[1],
>> + low_gm_end,
>> + dev_priv->gtt.mappable_end);
>> +
>> + if (ret)
>> + goto err;
>> + }
>
> Okay, I've figured it out. :) I suppose going back to patch 1, where it
> says "Each VM can only have one portion of continuous area for now",
> with the emphasis on _one_. That threw me off thinking you have two
> "balloons" meaning forbidden areas. And then with low and high naming I
> got the wrong idea that one balloon marks the bottom inaccessible part,
> and the other top. I didn't figure out the whole low == mappable, high
> == non-mappable split. I suppose it was my inexperience, but if you can
> think of a way on how to improve the comment, even ASCII art would be
> very nice if possible.
Hah. Guess I need a better comments above. Let me think how to organize. :)
>
> Actually ballooning in the first place confuses me because I thought
> prior use for that in virtualisation was for memory which can shrink and
> grow at runtime. Did I get that wrong?
>
Well, for memory virtualization, the word 'ballooning' does mean this -
it can shrink and grow.
Yet for our Intel GVT-g, the 'ballooning' is used, to emphasis that we
are not just partitioning the GM space to each vgpu, the vgpu can also
perceive its GM address space as starting from zero(although the usable
GM spaces may probably not).
By now, we do not grow/shrink. :)
>> + DRM_INFO("VGT balloon successfully\n");
>> + return 0;
>> +
>> +err:
>> + DRM_ERROR("VGT balloon fail\n");
>> + intel_vgt_deballoon();
>> + return ret;
>> +}
>> diff --git a/drivers/gpu/drm/i915/i915_vgpu.h
>> b/drivers/gpu/drm/i915/i915_vgpu.h
>> index 5f41d01c..f538b18 100644
>> --- a/drivers/gpu/drm/i915/i915_vgpu.h
>> +++ b/drivers/gpu/drm/i915/i915_vgpu.h
>> @@ -81,5 +81,7 @@ struct vgt_if {
>> (VGT_PVINFO_PAGE + (long)&((struct vgt_if *) NULL)->x)
>>
>> extern void i915_check_vgpu(struct drm_device *dev);
>> +extern int intel_vgt_balloon(struct drm_device *dev);
>> +extern void intel_vgt_deballoon(void);
>>
>> #endif /* _I915_VGPU_H_ */
>>
>
> Regards,
>
> Tvrtko
>
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2014-12-16 13:23 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-13 12:02 [PATCH v3 0/8] Add enlightenments for vGPU Yu Zhang
2014-11-13 12:02 ` [PATCH v3 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g Yu Zhang
2014-12-11 17:33 ` Tvrtko Ursulin
2014-12-15 8:12 ` Daniel Vetter
2014-12-16 12:51 ` Yu, Zhang
2014-12-16 13:19 ` Tvrtko Ursulin
2014-12-17 2:49 ` Yu, Zhang
2014-12-17 5:04 ` Tian, Kevin
2014-11-13 12:02 ` [PATCH v3 2/8] drm/i915: Adds graphic address space ballooning logic Yu Zhang
2014-11-14 10:16 ` Daniel Vetter
2014-11-14 12:00 ` Yu, Zhang
2014-12-12 13:00 ` Tvrtko Ursulin
2014-12-16 13:22 ` Yu, Zhang [this message]
2014-12-16 13:41 ` Tvrtko Ursulin
2014-12-16 14:39 ` Gerd Hoffmann
2014-12-16 15:15 ` Tvrtko Ursulin
2014-12-17 3:10 ` Yu, Zhang
2014-12-17 5:20 ` Tian, Kevin
2014-12-17 10:06 ` Tvrtko Ursulin
2014-12-17 5:57 ` Tian, Kevin
2014-11-13 12:02 ` [PATCH v3 3/8] drm/i915: Partition the fence registers for vGPU in i915 driver Yu Zhang
2014-12-12 13:07 ` Tvrtko Ursulin
2014-12-16 13:32 ` Yu, Zhang
2014-12-16 13:44 ` Tvrtko Ursulin
2014-12-16 14:41 ` Gerd Hoffmann
2014-12-16 15:01 ` Tvrtko Ursulin
2014-12-17 7:33 ` Gerd Hoffmann
2014-12-17 9:59 ` Tvrtko Ursulin
2014-12-17 11:06 ` Gerd Hoffmann
2014-12-17 11:25 ` Yu, Zhang
2014-12-17 11:50 ` Tvrtko Ursulin
2014-12-17 17:10 ` Daniel Vetter
2014-12-17 17:11 ` Daniel Vetter
2014-12-18 0:36 ` Tian, Kevin
2014-12-18 8:08 ` Daniel Vetter
2014-12-18 8:39 ` Tian, Kevin
2014-12-17 4:58 ` Tian, Kevin
2014-11-13 12:02 ` [PATCH v3 4/8] drm/i915: Disable framebuffer compression for i915 driver in VM Yu Zhang
2014-12-12 13:13 ` Tvrtko Ursulin
2014-12-17 3:15 ` Yu, Zhang
2014-11-13 12:02 ` [PATCH v3 5/8] drm/i915: Add the display switch logic for vGPU in i915 driver Yu Zhang
2014-12-12 13:18 ` Tvrtko Ursulin
2014-12-15 8:16 ` Daniel Vetter
2014-12-17 3:17 ` Yu, Zhang
2014-11-13 12:02 ` [PATCH v3 6/8] drm/i915: Disable power management for i915 driver in VM Yu Zhang
2014-12-12 13:27 ` Tvrtko Ursulin
2014-12-17 3:25 ` Yu, Zhang
2014-11-13 12:02 ` [PATCH v3 7/8] drm/i915: Create vGPU specific write MMIO to reduce traps Yu Zhang
2014-12-12 13:31 ` Tvrtko Ursulin
2014-12-17 7:28 ` Yu, Zhang
2014-11-13 12:02 ` [PATCH v3 8/8] drm/i915: Support alias ppgtt in VM if ppgtt is enabled Yu Zhang
2014-11-14 0:29 ` [PATCH v3 8/8] drm/i915: Support alias ppgtt in VM if shuang.he
2014-12-12 13:37 ` [PATCH v3 8/8] drm/i915: Support alias ppgtt in VM if ppgtt is enabled Tvrtko Ursulin
2014-11-14 10:17 ` [PATCH v3 0/8] Add enlightenments for vGPU Daniel Vetter
2014-11-14 12:01 ` Yu, Zhang
2014-12-11 17:03 ` Tvrtko Ursulin
2014-12-15 8:18 ` Daniel Vetter
2014-12-15 9:16 ` Jani Nikula
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=549031F9.8000108@linux.intel.com \
--to=yu.c.zhang@linux.intel.com \
--cc=Intel-gfx@lists.freedesktop.org \
--cc=tvrtko.ursulin@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox