[PATCH 27/66] drm/i915: Create a global list of vms

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



After we plumb our code to support multiple address spaces (VMs), there
are a few situations where we want to be able to traverse the list of
all address spaces in the system. Cases like eviction, or error state
collection are obvious example.

It's easy enough to test and make sure our list is accurate because we
already have a member in place to access our global GTT. By porting that
to use our list (which assumes the GGTT is always the first entry) we
can verify a decent amount of the code is working correct.

NOTE: to do this, we must initialize the list quite early.

Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_dma.c | 5 +++++
 drivers/gpu/drm/i915/i915_drv.h | 7 ++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 7d6d4b0..24dd593 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1497,6 +1497,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
 	i915_dump_device_info(dev_priv);
 
+	INIT_LIST_HEAD(&dev_priv->vm_list);
+	INIT_LIST_HEAD(&dev_priv->gtt.base.global_link);
+	list_add(&dev_priv->gtt.base.global_link, &dev_priv->vm_list);
+
 	if (i915_get_bridge_dev(dev)) {
 		ret = -EIO;
 		goto free_priv;
@@ -1753,6 +1757,7 @@ int i915_driver_unload(struct drm_device *dev)
 			i915_free_hws(dev);
 	}
 
+	list_del(&dev_priv->vm_list);
 	drm_mm_takedown(&i915_gtt_vm->mm);
 	if (dev_priv->regs != NULL)
 		pci_iounmap(dev->pdev, dev_priv->regs);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0553410..bc5f656 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -445,6 +445,7 @@ typedef uint32_t gen6_gtt_pte_t;
 struct i915_address_space {
 	struct drm_mm mm;
 	struct drm_device *dev;
+	struct list_head global_link;
 	unsigned long start;		/* Start offset always 0 for dri2 */
 	size_t total;		/* size addr space maps (ex. 2GB for ggtt) */
 
@@ -519,7 +520,10 @@ struct i915_gtt {
 			  unsigned long *mappable_end);
 	void (*gtt_remove)(struct drm_device *dev);
 };
-#define i915_gtt_vm ((struct i915_address_space *)&(dev_priv->gtt.base))
+#define i915_gtt_vm ((struct i915_address_space *) \
+		     list_first_entry(&dev_priv->vm_list,\
+				      struct i915_address_space, \
+				      global_link))
 
 struct i915_hw_ppgtt {
 	struct i915_address_space base;
@@ -1115,6 +1119,7 @@ typedef struct drm_i915_private {
 	enum modeset_restore modeset_restore;
 	struct mutex modeset_restore_lock;
 
+	struct list_head vm_list; /* Global list of all address spaces */
 	struct i915_gtt gtt; /* VMA representing the global address space */
 
 	struct i915_gem_mm mm;
-- 
1.8.3.1



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux