[PATCH V16 07/12] drm/xe/vram: Add page offline data structures and lifecycle
Tejas Upadhyay <[email protected]>
| Newsgroups | org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <[email protected]> |
Add xe_ttm_vram_offline_resource to track individual offlined VRAM pages, and extend xe_ttm_vram_mgr with offlined_pages/queued_pages lists and their counters. Initialize the lists in __xe_ttm_vram_mgr_init() and add xe_ttm_vram_free_bad_pages() to release all tracked pages during xe_ttm_vram_mgr_fini() teardown. v2(Himal): - Address possible leak in xe_ttm_vram_mgr_fini() - Remove unused dev and add comment for used_visible_size 0 Signed-off-by: Tejas Upadhyay <[email protected]> --- drivers/gpu/drm/xe/xe_ttm_vram_mgr.c | 25 +++++++++++++++++++ drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h | 28 ++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c index 49eeec90a470..1885f2aa64df 100644 --- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c +++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c @@ -300,6 +300,25 @@ static const struct ttm_resource_manager_func xe_ttm_vram_mgr_func = { .debug = xe_ttm_vram_mgr_debug }; +static void xe_ttm_vram_free_bad_pages(struct xe_ttm_vram_mgr *mgr) +{ + struct xe_ttm_vram_offline_resource *pos, *n; + + list_for_each_entry_safe(pos, n, &mgr->offlined_pages, offlined_link) { + xe_ttm_vram_buddy_free(mgr, &pos->blocks, pos->used_visible_size); + list_del_rcu(&pos->offlined_link); + --mgr->n_offlined_pages; + kfree_rcu(pos, rcu); + } + list_for_each_entry_safe(pos, n, &mgr->queued_pages, queued_link) { + /* queued entries have no buddy reservation yet */ + xe_ttm_vram_buddy_free(mgr, &pos->blocks, 0); + list_del_rcu(&pos->queued_link); + --mgr->n_queued_pages; + kfree_rcu(pos, rcu); + } +} + static void xe_ttm_vram_mgr_fini(struct drm_device *dev, void *arg) { struct xe_device *xe = to_xe_device(dev); @@ -308,6 +327,10 @@ static void xe_ttm_vram_mgr_fini(struct drm_device *dev, void *arg) ttm_resource_manager_set_used(man, false); + mutex_lock(&mgr->lock); + xe_ttm_vram_free_bad_pages(mgr); + mutex_unlock(&mgr->lock); + if (ttm_resource_manager_evict_all(&xe->ttm, man)) return; @@ -338,6 +361,8 @@ int __xe_ttm_vram_mgr_init(struct xe_device *xe, struct xe_ttm_vram_mgr *mgr, err = drmm_mutex_init(&xe->drm, &mgr->lock); if (err) return err; + INIT_LIST_HEAD(&mgr->offlined_pages); + INIT_LIST_HEAD(&mgr->queued_pages); mgr->default_page_size = default_page_size; mgr->visible_size = io_size; mgr->visible_avail = io_size; diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h b/drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h index 9106da056b49..9dc6fc5a3c38 100644 --- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h +++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h @@ -19,6 +19,14 @@ struct xe_ttm_vram_mgr { struct ttm_resource_manager manager; /** @mm: DRM buddy allocator which manages the VRAM */ struct gpu_buddy mm; + /** @offlined_pages: List of offlined pages */ + struct list_head offlined_pages; + /** @n_offlined_pages: Number of offlined pages */ + u16 n_offlined_pages; + /** @queued_pages: List of queued pages */ + struct list_head queued_pages; + /** @n_queued_pages: Number of queued pages */ + u16 n_queued_pages; /** @visible_size: Proped size of the CPU visible portion */ u64 visible_size; /** @visible_avail: CPU visible portion still unallocated */ @@ -45,4 +53,24 @@ struct xe_ttm_vram_mgr_resource { unsigned long flags; }; +/** + * struct xe_ttm_vram_offline_resource - Tracks a single offlined VRAM page + */ +struct xe_ttm_vram_offline_resource { + /** @offlined_link: Link into mgr->offlined_pages */ + struct list_head offlined_link; + /** @queued_link: Link into mgr->queued_pages */ + struct list_head queued_link; + /** @blocks: Buddy blocks reserved for this page */ + struct list_head blocks; + /** @used_visible_size: CPU-visible bytes consumed */ + u64 used_visible_size; + /** @addr: Faulty DPA reported by HW */ + u64 addr; + /** @status: Reservation status (0=pending, 1=fail) */ + bool status; + /** @rcu: RCU head for deferred freeing */ + struct rcu_head rcu; +}; + #endif -- 2.52.0