高通平臺採用gpu-mmu的時候發生視訊記憶體耗完而整個系統記憶體尚有的情況導致crash和重啟
阿新 • • 發佈:2019-02-03
原因在於kgsl_mmu.c中,定義了gpu使用的記憶體大小,7x30中限定了256MB,當視訊記憶體耗光而記憶體尚剩餘很多的時候就會發生問題:不能觸發LMK或OOM來釋放記憶體,而又沒有視訊記憶體可用,進而可能引起各程序watchdogtimeout,如果系統程序發生watchdogtimeout,會導致system serverrestart,而restart之後也不能釋放gpu視訊記憶體,會一直反覆重啟:
unsigned int kgsl_mmu_get_ptsize(void) { /* * For IOMMU, we could do up to 4G virtual range if we wanted to, but * it makes more sense to return a smaller range and leave the rest of * the virtual range for future improvements */ if (KGSL_MMU_TYPE_GPU == kgsl_mmu_type) return CONFIG_MSM_KGSL_PAGE_TABLE_SIZE; else if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_type) return SZ_2G - KGSL_PAGETABLE_BASE; else return 0; }
Lowmemorykiller.c 新增一個新函式
void lowmem_shrink_gpu(void) { struct task_struct *tsk; struct task_struct *selected = NULL; int tasksize; int selected_tasksize = 0; rcu_read_lock(); for_each_process(tsk) { struct task_struct *p; if (tsk->flags & PF_KTHREAD) continue; p = find_lock_task_mm(tsk); if (!p) continue; if (test_tsk_thread_flag(p, TIF_MEMDIE) && time_before_eq(jiffies, lowmem_deathpending_timeout)) { task_unlock(p); rcu_read_unlock(); return ; } tasksize = get_mm_rss(p->mm); task_unlock(p); if ((tasksize <= 0) || (p->signal->oom_score_adj <= 1)) continue; if (selected) { if (tasksize <= selected_tasksize) continue; } selected = p; selected_tasksize = tasksize; lowmem_print(2, "AKeywordSE select %d (%s), size %d, to kill\n", p->pid, p->comm, tasksize); } if (selected) { lowmem_print(1, "AKeywordSE send sigkill to %d (%s), size %d\n", selected->pid, selected->comm,selected_tasksize); lowmem_deathpending_timeout = jiffies + HZ; send_sig(SIGKILL, selected, 0); set_tsk_thread_flag(selected, TIF_MEMDIE); } rcu_read_unlock(); return ; }
Kgs_mmu.c中宣告
extern void lowmem_shrink_gpu(void );
並在kgsl_mmu_map中呼叫
if (memdesc->gpuaddr == 0) { lowmem_shrink_gpu(); KGSL_CORE_ERR("gen_pool_alloc(%d) failed from pool: %s\n", size, (pool == pagetable->kgsl_pool) ? "kgsl_pool" : "general_pool"); KGSL_CORE_ERR(" [%d] allocated=%d, entries=%d\n", pagetable->name, pagetable->stats.mapped, pagetable->stats.entries); return -ENOMEM; }