Loading drivers/gpu/msm/kgsl_mmu.c +23 −52 Original line number Original line Diff line number Diff line Loading @@ -230,41 +230,27 @@ int kgsl_add_global_pt_entry(struct kgsl_device *device, } } EXPORT_SYMBOL(kgsl_add_global_pt_entry); EXPORT_SYMBOL(kgsl_add_global_pt_entry); static void _kgsl_destroy_pagetable(struct kgsl_pagetable *pagetable) { pagetable_remove_sysfs_objects(pagetable); kgsl_unmap_global_pt_entries(pagetable); if (pagetable->pool) gen_pool_destroy(pagetable->pool); pagetable->pt_ops->mmu_destroy_pagetable(pagetable); kfree(pagetable); } static void kgsl_destroy_pagetable(struct kref *kref) static void kgsl_destroy_pagetable(struct kref *kref) { { struct kgsl_pagetable *pagetable = container_of(kref, struct kgsl_pagetable *pagetable = container_of(kref, struct kgsl_pagetable, refcount); struct kgsl_pagetable, refcount); unsigned long flags; unsigned long flags; spin_lock_irqsave(&kgsl_driver.ptlock, flags); spin_lock_irqsave(&kgsl_driver.ptlock, flags); list_del(&pagetable->list); list_del(&pagetable->list); spin_unlock_irqrestore(&kgsl_driver.ptlock, flags); spin_unlock_irqrestore(&kgsl_driver.ptlock, flags); _kgsl_destroy_pagetable(pagetable); pagetable_remove_sysfs_objects(pagetable); } static void kgsl_destroy_pagetable_locked(struct kref *kref) kgsl_unmap_global_pt_entries(pagetable); { struct kgsl_pagetable *pagetable = container_of(kref, struct kgsl_pagetable, refcount); list_del(&pagetable->list); if (pagetable->pool) gen_pool_destroy(pagetable->pool); pagetable->pt_ops->mmu_destroy_pagetable(pagetable); _kgsl_destroy_pagetable(pagetable); kfree(pagetable); } } static inline void kgsl_put_pagetable(struct kgsl_pagetable *pagetable) static inline void kgsl_put_pagetable(struct kgsl_pagetable *pagetable) Loading @@ -281,13 +267,10 @@ kgsl_get_pagetable(unsigned long name) spin_lock_irqsave(&kgsl_driver.ptlock, flags); spin_lock_irqsave(&kgsl_driver.ptlock, flags); list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { if (kref_get_unless_zero(&pt->refcount)) { if (name == pt->name && kref_get_unless_zero(&pt->refcount)) { if (pt->name == name) { ret = pt; ret = pt; break; break; } } kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); } } } spin_unlock_irqrestore(&kgsl_driver.ptlock, flags); spin_unlock_irqrestore(&kgsl_driver.ptlock, flags); Loading Loading @@ -433,15 +416,10 @@ kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, phys_addr_t pt_base) return KGSL_MMU_GLOBAL_PT; return KGSL_MMU_GLOBAL_PT; spin_lock(&kgsl_driver.ptlock); spin_lock(&kgsl_driver.ptlock); list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { if (kref_get_unless_zero(&pt->refcount)) { if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) { if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) { ptid = (int) pt->name; ptid = (int) pt->name; kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); break; break; } } kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); } } } spin_unlock(&kgsl_driver.ptlock); spin_unlock(&kgsl_driver.ptlock); Loading @@ -460,24 +438,17 @@ kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, phys_addr_t pt_base, return 0; return 0; spin_lock(&kgsl_driver.ptlock); spin_lock(&kgsl_driver.ptlock); list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { if (kref_get_unless_zero(&pt->refcount)) { if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) { if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) { if ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) { if ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) { ret = 1; ret = 1; kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); break; break; } else { } else { pt->fault_addr = pt->fault_addr = (addr & ~(PAGE_SIZE-1)); (addr & ~(PAGE_SIZE-1)); ret = 0; ret = 0; kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); break; break; } } } } kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); } } } spin_unlock(&kgsl_driver.ptlock); spin_unlock(&kgsl_driver.ptlock); Loading Loading
drivers/gpu/msm/kgsl_mmu.c +23 −52 Original line number Original line Diff line number Diff line Loading @@ -230,41 +230,27 @@ int kgsl_add_global_pt_entry(struct kgsl_device *device, } } EXPORT_SYMBOL(kgsl_add_global_pt_entry); EXPORT_SYMBOL(kgsl_add_global_pt_entry); static void _kgsl_destroy_pagetable(struct kgsl_pagetable *pagetable) { pagetable_remove_sysfs_objects(pagetable); kgsl_unmap_global_pt_entries(pagetable); if (pagetable->pool) gen_pool_destroy(pagetable->pool); pagetable->pt_ops->mmu_destroy_pagetable(pagetable); kfree(pagetable); } static void kgsl_destroy_pagetable(struct kref *kref) static void kgsl_destroy_pagetable(struct kref *kref) { { struct kgsl_pagetable *pagetable = container_of(kref, struct kgsl_pagetable *pagetable = container_of(kref, struct kgsl_pagetable, refcount); struct kgsl_pagetable, refcount); unsigned long flags; unsigned long flags; spin_lock_irqsave(&kgsl_driver.ptlock, flags); spin_lock_irqsave(&kgsl_driver.ptlock, flags); list_del(&pagetable->list); list_del(&pagetable->list); spin_unlock_irqrestore(&kgsl_driver.ptlock, flags); spin_unlock_irqrestore(&kgsl_driver.ptlock, flags); _kgsl_destroy_pagetable(pagetable); pagetable_remove_sysfs_objects(pagetable); } static void kgsl_destroy_pagetable_locked(struct kref *kref) kgsl_unmap_global_pt_entries(pagetable); { struct kgsl_pagetable *pagetable = container_of(kref, struct kgsl_pagetable, refcount); list_del(&pagetable->list); if (pagetable->pool) gen_pool_destroy(pagetable->pool); pagetable->pt_ops->mmu_destroy_pagetable(pagetable); _kgsl_destroy_pagetable(pagetable); kfree(pagetable); } } static inline void kgsl_put_pagetable(struct kgsl_pagetable *pagetable) static inline void kgsl_put_pagetable(struct kgsl_pagetable *pagetable) Loading @@ -281,13 +267,10 @@ kgsl_get_pagetable(unsigned long name) spin_lock_irqsave(&kgsl_driver.ptlock, flags); spin_lock_irqsave(&kgsl_driver.ptlock, flags); list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { if (kref_get_unless_zero(&pt->refcount)) { if (name == pt->name && kref_get_unless_zero(&pt->refcount)) { if (pt->name == name) { ret = pt; ret = pt; break; break; } } kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); } } } spin_unlock_irqrestore(&kgsl_driver.ptlock, flags); spin_unlock_irqrestore(&kgsl_driver.ptlock, flags); Loading Loading @@ -433,15 +416,10 @@ kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, phys_addr_t pt_base) return KGSL_MMU_GLOBAL_PT; return KGSL_MMU_GLOBAL_PT; spin_lock(&kgsl_driver.ptlock); spin_lock(&kgsl_driver.ptlock); list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { if (kref_get_unless_zero(&pt->refcount)) { if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) { if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) { ptid = (int) pt->name; ptid = (int) pt->name; kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); break; break; } } kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); } } } spin_unlock(&kgsl_driver.ptlock); spin_unlock(&kgsl_driver.ptlock); Loading @@ -460,24 +438,17 @@ kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, phys_addr_t pt_base, return 0; return 0; spin_lock(&kgsl_driver.ptlock); spin_lock(&kgsl_driver.ptlock); list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) { if (kref_get_unless_zero(&pt->refcount)) { if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) { if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) { if ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) { if ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) { ret = 1; ret = 1; kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); break; break; } else { } else { pt->fault_addr = pt->fault_addr = (addr & ~(PAGE_SIZE-1)); (addr & ~(PAGE_SIZE-1)); ret = 0; ret = 0; kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); break; break; } } } } kref_put(&pt->refcount, kgsl_destroy_pagetable_locked); } } } spin_unlock(&kgsl_driver.ptlock); spin_unlock(&kgsl_driver.ptlock); Loading