drm/nvc0/fb: take lock in nvc0_ram_put()
Kernel panic caused by list corruption in ltcg seems to indicate a concurrency issue. Take mutex of pfb like nv50_ram_put() to eliminate concurrency. V2: Separate critical section into separate function, avoid taking the lock twice on NVC0 Signed-off-by: Roy Spliet <r.spliet@student.tudelft.nl> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Родитель
bfcd92a0ae
Коммит
dedaa8f0e6
|
@ -81,7 +81,7 @@ void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
|
|||
void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
|
||||
u32 pitch, u32 flags, struct nouveau_fb_tile *);
|
||||
|
||||
void nv50_ram_put(struct nouveau_fb *, struct nouveau_mem **);
|
||||
void __nv50_ram_put(struct nouveau_fb *, struct nouveau_mem *);
|
||||
extern int nv50_fb_memtype[0x80];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,17 +27,10 @@
|
|||
#include "priv.h"
|
||||
|
||||
void
|
||||
nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
|
||||
__nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem)
|
||||
{
|
||||
struct nouveau_mm_node *this;
|
||||
struct nouveau_mem *mem;
|
||||
|
||||
mem = *pmem;
|
||||
*pmem = NULL;
|
||||
if (unlikely(mem == NULL))
|
||||
return;
|
||||
|
||||
mutex_lock(&pfb->base.mutex);
|
||||
while (!list_empty(&mem->regions)) {
|
||||
this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
|
||||
|
||||
|
@ -46,6 +39,19 @@ nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
|
|||
}
|
||||
|
||||
nouveau_mm_free(&pfb->tags, &mem->tag);
|
||||
}
|
||||
|
||||
void
|
||||
nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
|
||||
{
|
||||
struct nouveau_mem *mem = *pmem;
|
||||
|
||||
*pmem = NULL;
|
||||
if (unlikely(mem == NULL))
|
||||
return;
|
||||
|
||||
mutex_lock(&pfb->base.mutex);
|
||||
__nv50_ram_put(pfb, mem);
|
||||
mutex_unlock(&pfb->base.mutex);
|
||||
|
||||
kfree(mem);
|
||||
|
|
|
@ -33,11 +33,19 @@ void
|
|||
nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
|
||||
{
|
||||
struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb);
|
||||
struct nouveau_mem *mem = *pmem;
|
||||
|
||||
if ((*pmem)->tag)
|
||||
ltcg->tags_free(ltcg, &(*pmem)->tag);
|
||||
*pmem = NULL;
|
||||
if (unlikely(mem == NULL))
|
||||
return;
|
||||
|
||||
nv50_ram_put(pfb, pmem);
|
||||
mutex_lock(&pfb->base.mutex);
|
||||
if (mem->tag)
|
||||
ltcg->tags_free(ltcg, &mem->tag);
|
||||
__nv50_ram_put(pfb, mem);
|
||||
mutex_unlock(&pfb->base.mutex);
|
||||
|
||||
kfree(mem);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Загрузка…
Ссылка в новой задаче