Merge "msm: kgsl: Take the pagetable reference count only when needed"
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
old mode 100644
new mode 100755
index 65e607b..4591165
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -85,8 +85,17 @@
return status;
}
-static void _kgsl_destroy_pagetable(struct kgsl_pagetable *pagetable)
+static void kgsl_destroy_pagetable(struct kref *kref)
{
+ struct kgsl_pagetable *pagetable = container_of(kref,
+ struct kgsl_pagetable, refcount);
+
+ unsigned long flags;
+
+ spin_lock_irqsave(&kgsl_driver.ptlock, flags);
+ list_del(&pagetable->list);
+ spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);
+
pagetable_remove_sysfs_objects(pagetable);
kgsl_cleanup_pt(pagetable);
@@ -101,29 +110,6 @@
kfree(pagetable);
}
-static void kgsl_destroy_pagetable(struct kref *kref)
-{
- struct kgsl_pagetable *pagetable = container_of(kref,
- struct kgsl_pagetable, refcount);
- unsigned long flags;
-
- spin_lock_irqsave(&kgsl_driver.ptlock, flags);
- list_del(&pagetable->list);
- spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);
-
- _kgsl_destroy_pagetable(pagetable);
-}
-
-static void kgsl_destroy_pagetable_locked(struct kref *kref)
-{
- struct kgsl_pagetable *pagetable = container_of(kref,
- struct kgsl_pagetable, refcount);
-
- list_del(&pagetable->list);
-
- _kgsl_destroy_pagetable(pagetable);
-}
-
static inline void kgsl_put_pagetable(struct kgsl_pagetable *pagetable)
{
if (pagetable)
@@ -138,12 +124,9 @@
spin_lock_irqsave(&kgsl_driver.ptlock, flags);
list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
- if (kref_get_unless_zero(&pt->refcount)) {
- if (pt->name == name) {
- ret = pt;
- break;
- }
- kref_put(&pt->refcount, kgsl_destroy_pagetable_locked);
+ if (name == pt->name && kref_get_unless_zero(&pt->refcount)) {
+ ret = pt;
+ break;
}
}
@@ -340,14 +323,9 @@
return KGSL_MMU_GLOBAL_PT;
spin_lock(&kgsl_driver.ptlock);
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)) {
- ptid = (int) pt->name;
- kref_put(&pt->refcount,
- kgsl_destroy_pagetable_locked);
- break;
- }
- kref_put(&pt->refcount, kgsl_destroy_pagetable_locked);
+ if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
+ ptid = (int) pt->name;
+ break;
}
}
spin_unlock(&kgsl_driver.ptlock);
@@ -367,23 +345,16 @@
return 0;
spin_lock(&kgsl_driver.ptlock);
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 ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) {
- ret = 1;
- kref_put(&pt->refcount,
- kgsl_destroy_pagetable_locked);
- break;
- } else {
- pt->fault_addr =
- (addr & ~(PAGE_SIZE-1));
- ret = 0;
- kref_put(&pt->refcount,
- kgsl_destroy_pagetable_locked);
- break;
- }
+ if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
+ if ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) {
+ ret = 1;
+ break;
+ } else {
+ pt->fault_addr =
+ (addr & ~(PAGE_SIZE-1));
+ ret = 0;
+ break;
}
- kref_put(&pt->refcount, kgsl_destroy_pagetable_locked);
}
}
spin_unlock(&kgsl_driver.ptlock);