From: Matthew Wilcox Date: Tue, 23 Oct 2018 18:36:36 +0000 (-0400) Subject: drm/i915: Convert spt_tree to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=edc671dc6483dbccf4e54e99d73c578998575ac8;p=users%2Fwilly%2Fxarray.git drm/i915: Convert spt_tree to XArray A straightforward conversion. Notice the XArray does not suffer from exposing the RCU problem to its users like the radix tree did. Signed-off-by: Matthew Wilcox --- diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 4b04af569c05c..87a77bad6e6da 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -741,7 +741,7 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt) dma_unmap_page(kdev, spt->shadow_page.mfn << I915_GTT_PAGE_SHIFT, 4096, PCI_DMA_BIDIRECTIONAL); - radix_tree_delete(&spt->vgpu->gtt.spt_tree, spt->shadow_page.mfn); + xa_erase(&spt->vgpu->gtt.spts, spt->shadow_page.mfn); if (spt->guest_page.gfn) { if (spt->guest_page.oos_page) @@ -756,19 +756,10 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt) static void ppgtt_free_all_spt(struct intel_vgpu *vgpu) { - struct intel_vgpu_ppgtt_spt *spt, *spn; - struct radix_tree_iter iter; - LIST_HEAD(all_spt); - void __rcu **slot; - - rcu_read_lock(); - radix_tree_for_each_slot(slot, &vgpu->gtt.spt_tree, &iter, 0) { - spt = radix_tree_deref_slot(slot); - list_move(&spt->post_shadow_list, &all_spt); - } - rcu_read_unlock(); + struct intel_vgpu_ppgtt_spt *spt; + unsigned long index; - list_for_each_entry_safe(spt, spn, &all_spt, post_shadow_list) + xa_for_each(&vgpu->gtt.spts, index, spt) ppgtt_free_spt(spt); } @@ -810,7 +801,7 @@ static struct intel_vgpu_ppgtt_spt *intel_vgpu_find_spt_by_gfn( static inline struct intel_vgpu_ppgtt_spt *intel_vgpu_find_spt_by_mfn( struct intel_vgpu *vgpu, unsigned long mfn) { - return radix_tree_lookup(&vgpu->gtt.spt_tree, mfn); + return xa_load(&vgpu->gtt.spts, mfn); } static int reclaim_one_ppgtt_mm(struct intel_gvt *gvt); @@ -852,13 +843,13 @@ retry: spt->shadow_page.vaddr = page_address(spt->shadow_page.page); spt->shadow_page.mfn = daddr >> I915_GTT_PAGE_SHIFT; - ret = radix_tree_insert(&vgpu->gtt.spt_tree, spt->shadow_page.mfn, spt); - if (ret) + if (xa_store(&vgpu->gtt.spts, spt->shadow_page.mfn, spt, GFP_KERNEL)) goto err_unmap_dma; return spt; err_unmap_dma: + ret = -ENOMEM; dma_unmap_page(kdev, daddr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); err_free_spt: free_spt(spt); @@ -2454,7 +2445,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) { struct intel_vgpu_gtt *gtt = &vgpu->gtt; - INIT_RADIX_TREE(>t->spt_tree, GFP_KERNEL); + xa_init(>t->spts); INIT_LIST_HEAD(>t->ppgtt_mm_list_head); INIT_LIST_HEAD(>t->oos_page_list_head); @@ -2486,7 +2477,7 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu) if (GEM_WARN_ON(!list_empty(&vgpu->gtt.ppgtt_mm_list_head))) gvt_err("vgpu ppgtt mm is not fully destroyed\n"); - if (GEM_WARN_ON(!radix_tree_empty(&vgpu->gtt.spt_tree))) { + if (GEM_WARN_ON(!xa_empty(&vgpu->gtt.spts))) { gvt_err("Why we still has spt not freed?\n"); ppgtt_free_all_spt(vgpu); } diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index 42d0394f0de2b..b5834a13c599a 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h @@ -199,7 +199,7 @@ struct intel_vgpu_gtt { struct intel_vgpu_mm *ggtt_mm; unsigned long active_ppgtt_mm_bitmap; struct list_head ppgtt_mm_list_head; - struct radix_tree_root spt_tree; + struct xarray spts; struct list_head oos_page_list_head; struct list_head post_shadow_list_head; struct intel_vgpu_scratch_pt scratch_pt[GTT_TYPE_MAX]; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fe7a6ec2c199c..4998250bb2aaa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include /* for struct drm_dma_handle */