Commit d7126c0c authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-xe-next-fixes-2024-09-19' of...

Merge tag 'drm-xe-next-fixes-2024-09-19' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next

Driver Changes:
- Fix macro for checking minimum GuC version (Michal Wajdeczko)
- Fix CCS offset calculation for some BMG SKUs (Matthew Auld)
- Fix locking on memory usage reporting via fdinfo and BO destroy (Matthew Auld)
- Fix GPU page fault handler on a closed VM (Matthew Brost)
- Fix overflow in oa batch buffer (José)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/lr6vhd7x5eb7gubd7utfmnwzvfqfslji4kssxyqisynzlvqjni@svgm6jot7r66
parents 338aae54 6c10ba06
...@@ -65,6 +65,7 @@ __xe_bb_create_job(struct xe_exec_queue *q, struct xe_bb *bb, u64 *addr) ...@@ -65,6 +65,7 @@ __xe_bb_create_job(struct xe_exec_queue *q, struct xe_bb *bb, u64 *addr)
{ {
u32 size = drm_suballoc_size(bb->bo); u32 size = drm_suballoc_size(bb->bo);
if (bb->len == 0 || bb->cs[bb->len - 1] != MI_BATCH_BUFFER_END)
bb->cs[bb->len++] = MI_BATCH_BUFFER_END; bb->cs[bb->len++] = MI_BATCH_BUFFER_END;
xe_gt_assert(q->gt, bb->len * 4 + bb_prefetch(q->gt) <= size); xe_gt_assert(q->gt, bb->len * 4 + bb_prefetch(q->gt) <= size);
......
...@@ -2320,6 +2320,20 @@ void xe_bo_put_commit(struct llist_head *deferred) ...@@ -2320,6 +2320,20 @@ void xe_bo_put_commit(struct llist_head *deferred)
drm_gem_object_free(&bo->ttm.base.refcount); drm_gem_object_free(&bo->ttm.base.refcount);
} }
void xe_bo_put(struct xe_bo *bo)
{
might_sleep();
if (bo) {
#ifdef CONFIG_PROC_FS
if (bo->client)
might_lock(&bo->client->bos_lock);
#endif
if (bo->ggtt_node && bo->ggtt_node->ggtt)
might_lock(&bo->ggtt_node->ggtt->lock);
drm_gem_object_put(&bo->ttm.base);
}
}
/** /**
* xe_bo_dumb_create - Create a dumb bo as backing for a fb * xe_bo_dumb_create - Create a dumb bo as backing for a fb
* @file_priv: ... * @file_priv: ...
......
...@@ -126,11 +126,7 @@ static inline struct xe_bo *xe_bo_get(struct xe_bo *bo) ...@@ -126,11 +126,7 @@ static inline struct xe_bo *xe_bo_get(struct xe_bo *bo)
return bo; return bo;
} }
static inline void xe_bo_put(struct xe_bo *bo) void xe_bo_put(struct xe_bo *bo);
{
if (bo)
drm_gem_object_put(&bo->ttm.base);
}
static inline void __xe_bo_unset_bulk_move(struct xe_bo *bo) static inline void __xe_bo_unset_bulk_move(struct xe_bo *bo)
{ {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#include "xe_assert.h"
#include "xe_bo.h" #include "xe_bo.h"
#include "xe_bo_types.h" #include "xe_bo_types.h"
#include "xe_device_types.h" #include "xe_device_types.h"
...@@ -151,10 +152,13 @@ void xe_drm_client_add_bo(struct xe_drm_client *client, ...@@ -151,10 +152,13 @@ void xe_drm_client_add_bo(struct xe_drm_client *client,
*/ */
void xe_drm_client_remove_bo(struct xe_bo *bo) void xe_drm_client_remove_bo(struct xe_bo *bo)
{ {
struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev);
struct xe_drm_client *client = bo->client; struct xe_drm_client *client = bo->client;
xe_assert(xe, !kref_read(&bo->ttm.base.refcount));
spin_lock(&client->bos_lock); spin_lock(&client->bos_lock);
list_del(&bo->client_link); list_del_init(&bo->client_link);
spin_unlock(&client->bos_lock); spin_unlock(&client->bos_lock);
xe_drm_client_put(client); xe_drm_client_put(client);
...@@ -164,12 +168,9 @@ static void bo_meminfo(struct xe_bo *bo, ...@@ -164,12 +168,9 @@ static void bo_meminfo(struct xe_bo *bo,
struct drm_memory_stats stats[TTM_NUM_MEM_TYPES]) struct drm_memory_stats stats[TTM_NUM_MEM_TYPES])
{ {
u64 sz = bo->size; u64 sz = bo->size;
u32 mem_type; u32 mem_type = bo->ttm.resource->mem_type;
if (bo->placement.placement) xe_bo_assert_held(bo);
mem_type = bo->placement.placement->mem_type;
else
mem_type = XE_PL_TT;
if (drm_gem_object_is_shared_for_memory_stats(&bo->ttm.base)) if (drm_gem_object_is_shared_for_memory_stats(&bo->ttm.base))
stats[mem_type].shared += sz; stats[mem_type].shared += sz;
...@@ -196,6 +197,7 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file) ...@@ -196,6 +197,7 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
struct xe_drm_client *client; struct xe_drm_client *client;
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct xe_bo *bo; struct xe_bo *bo;
LLIST_HEAD(deferred);
unsigned int id; unsigned int id;
u32 mem_type; u32 mem_type;
...@@ -206,7 +208,20 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file) ...@@ -206,7 +208,20 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
idr_for_each_entry(&file->object_idr, obj, id) { idr_for_each_entry(&file->object_idr, obj, id) {
struct xe_bo *bo = gem_to_xe_bo(obj); struct xe_bo *bo = gem_to_xe_bo(obj);
if (dma_resv_trylock(bo->ttm.base.resv)) {
bo_meminfo(bo, stats);
xe_bo_unlock(bo);
} else {
xe_bo_get(bo);
spin_unlock(&file->table_lock);
xe_bo_lock(bo, false);
bo_meminfo(bo, stats); bo_meminfo(bo, stats);
xe_bo_unlock(bo);
xe_bo_put(bo);
spin_lock(&file->table_lock);
}
} }
spin_unlock(&file->table_lock); spin_unlock(&file->table_lock);
...@@ -215,11 +230,28 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file) ...@@ -215,11 +230,28 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
list_for_each_entry(bo, &client->bos_list, client_link) { list_for_each_entry(bo, &client->bos_list, client_link) {
if (!kref_get_unless_zero(&bo->ttm.base.refcount)) if (!kref_get_unless_zero(&bo->ttm.base.refcount))
continue; continue;
if (dma_resv_trylock(bo->ttm.base.resv)) {
bo_meminfo(bo, stats); bo_meminfo(bo, stats);
xe_bo_put(bo); xe_bo_unlock(bo);
} else {
spin_unlock(&client->bos_lock);
xe_bo_lock(bo, false);
bo_meminfo(bo, stats);
xe_bo_unlock(bo);
spin_lock(&client->bos_lock);
/* The bo ref will prevent this bo from being removed from the list */
xe_assert(xef->xe, !list_empty(&bo->client_link));
}
xe_bo_put_deferred(bo, &deferred);
} }
spin_unlock(&client->bos_lock); spin_unlock(&client->bos_lock);
xe_bo_put_commit(&deferred);
for (mem_type = XE_PL_SYSTEM; mem_type < TTM_NUM_MEM_TYPES; ++mem_type) { for (mem_type = XE_PL_SYSTEM; mem_type < TTM_NUM_MEM_TYPES; ++mem_type) {
if (!xe_mem_type_to_name[mem_type]) if (!xe_mem_type_to_name[mem_type])
continue; continue;
......
...@@ -212,6 +212,12 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) ...@@ -212,6 +212,12 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
* TODO: Change to read lock? Using write lock for simplicity. * TODO: Change to read lock? Using write lock for simplicity.
*/ */
down_write(&vm->lock); down_write(&vm->lock);
if (xe_vm_is_closed(vm)) {
err = -ENOENT;
goto unlock_vm;
}
vma = lookup_vma(vm, pf->page_addr); vma = lookup_vma(vm, pf->page_addr);
if (!vma) { if (!vma) {
err = -EINVAL; err = -EINVAL;
......
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
*/ */
#define MAKE_GUC_VER(maj, min, pat) (((maj) << 16) | ((min) << 8) | (pat)) #define MAKE_GUC_VER(maj, min, pat) (((maj) << 16) | ((min) << 8) | (pat))
#define MAKE_GUC_VER_STRUCT(ver) MAKE_GUC_VER((ver).major, (ver).minor, (ver).patch) #define MAKE_GUC_VER_STRUCT(ver) MAKE_GUC_VER((ver).major, (ver).minor, (ver).patch)
#define GUC_SUBMIT_VER(guc) MAKE_VER_STRUCT((guc)->fw.versions.found[XE_UC_FW_VER_COMPATIBILITY]) #define GUC_SUBMIT_VER(guc) \
#define GUC_FIRMWARE_VER(guc) MAKE_VER_STRUCT((guc)->fw.versions.found[XE_UC_FW_VER_RELEASE]) MAKE_GUC_VER_STRUCT((guc)->fw.versions.found[XE_UC_FW_VER_COMPATIBILITY])
#define GUC_FIRMWARE_VER(guc) \
MAKE_GUC_VER_STRUCT((guc)->fw.versions.found[XE_UC_FW_VER_RELEASE])
struct drm_printer; struct drm_printer;
......
...@@ -182,6 +182,7 @@ static inline u64 get_flat_ccs_offset(struct xe_gt *gt, u64 tile_size) ...@@ -182,6 +182,7 @@ static inline u64 get_flat_ccs_offset(struct xe_gt *gt, u64 tile_size)
offset = offset_hi << 32; /* HW view bits 39:32 */ offset = offset_hi << 32; /* HW view bits 39:32 */
offset |= offset_lo << 6; /* HW view bits 31:6 */ offset |= offset_lo << 6; /* HW view bits 31:6 */
offset *= num_enabled; /* convert to SW view */ offset *= num_enabled; /* convert to SW view */
offset = round_up(offset, SZ_128K); /* SW must round up to nearest 128K */
/* We don't expect any holes */ /* We don't expect any holes */
xe_assert_msg(xe, offset == (xe_mmio_read64_2x32(gt, GSMBASE) - ccs_size), xe_assert_msg(xe, offset == (xe_mmio_read64_2x32(gt, GSMBASE) - ccs_size),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment