From 3fa47b877db1edc16018d662e7b9915d92354745 Mon Sep 17 00:00:00 2001 From: Debarshi Dutta Date: Tue, 8 Aug 2017 12:08:03 +0530 Subject: gpu: nvgpu: Replace kref for refcounting in nvgpu - added wrapper struct nvgpu_ref over nvgpu_atomic_t - added nvgpu_ref_* APIs to access the above struct JIRA NVGPU-140 Change-Id: Id47f897995dd4721751f7610b6d4d4fbfe4d6b9a Signed-off-by: Debarshi Dutta Reviewed-on: https://git-master.nvidia.com/r/1540899 Reviewed-by: svc-mobile-coverity Reviewed-by: svccoveritychecker GVS: Gerrit_Virtual_Submit Reviewed-by: Konsta Holtta Reviewed-by: Vijayakumar Subbu --- drivers/gpu/nvgpu/include/nvgpu/atomic.h | 8 ++++ drivers/gpu/nvgpu/include/nvgpu/kref.h | 63 ++++++++++++++++++++++++-- drivers/gpu/nvgpu/include/nvgpu/linux/atomic.h | 10 ++++ drivers/gpu/nvgpu/include/nvgpu/semaphore.h | 4 +- drivers/gpu/nvgpu/include/nvgpu/vm.h | 4 +- 5 files changed, 82 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/nvgpu/include') diff --git a/drivers/gpu/nvgpu/include/nvgpu/atomic.h b/drivers/gpu/nvgpu/include/nvgpu/atomic.h index c7a5fcd9..393a9d35 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/atomic.h +++ b/drivers/gpu/nvgpu/include/nvgpu/atomic.h @@ -61,10 +61,18 @@ static inline bool nvgpu_atomic_dec_and_test(nvgpu_atomic_t *v) { return __nvgpu_atomic_dec_and_test(v); } +static inline bool nvgpu_atomic_sub_and_test(int i, nvgpu_atomic_t *v) +{ + return __nvgpu_atomic_sub_and_test(i, v); +} static inline int nvgpu_atomic_add_return(int i, nvgpu_atomic_t *v) { return __nvgpu_atomic_add_return(i, v); } +static inline int nvgpu_atomic_add_unless(nvgpu_atomic_t *v, int a, int u) +{ + return __nvgpu_atomic_add_unless(v, a, u); +} static inline void nvgpu_atomic64_set(nvgpu_atomic64_t *v, long i) { return __nvgpu_atomic64_set(v, i); diff --git a/drivers/gpu/nvgpu/include/nvgpu/kref.h b/drivers/gpu/nvgpu/include/nvgpu/kref.h index d24db603..fd2b456f 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/kref.h +++ b/drivers/gpu/nvgpu/include/nvgpu/kref.h @@ -10,11 +10,68 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. */ + +/* + * The following structure is used for reference counting of objects in nvgpu. + */ #ifndef __NVGPU_KREF_H__ #define __NVGPU_KREF_H__ -#ifdef __KERNEL__ -#include -#endif +#include + +struct nvgpu_ref { + nvgpu_atomic_t refcount; +}; + +/* + * Initialize object. + * @ref: the nvgpu_ref object to initialize + */ +static inline void nvgpu_ref_init(struct nvgpu_ref *ref) +{ + nvgpu_atomic_set(&ref->refcount, 1); +} + +/* + * Increment reference count for the object + * @ref: the nvgpu_ref object + */ +static inline void nvgpu_ref_get(struct nvgpu_ref *ref) +{ + nvgpu_atomic_inc(&ref->refcount); +} + +/* + * Decrement reference count for the object and call release() if it becomes + * zero. + * @ref: the nvgpu_ref object + * @release: pointer to the function that would be invoked to clean up the + * object when the reference count becomes zero, i.e. the last + * reference corresponding to this object is removed. + * Return 1 if object was removed, otherwise return 0. The user should not + * make any assumptions about the status of the object in the memory when + * the function returns 0 and should only use it to know that there are no + * further references to this object. + */ +static inline int nvgpu_ref_put(struct nvgpu_ref *ref, + void (*release)(struct nvgpu_ref *r)) +{ + if (nvgpu_atomic_sub_and_test(1, &ref->refcount)) { + if (release != NULL) + release(ref); + return 1; + } + return 0; +} + +/* + * Increment reference count for the object unless it is zero. + * @ref: the nvgpu_ref object + * Return non-zero if the increment succeeds, Otherwise return 0. + */ +static inline int __must_check nvgpu_ref_get_unless_zero(struct nvgpu_ref *ref) +{ + return nvgpu_atomic_add_unless(&ref->refcount, 1, 0); +} #endif /* __NVGPU_KREF_H__ */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/atomic.h b/drivers/gpu/nvgpu/include/nvgpu/linux/atomic.h index 1fdb2674..0734672e 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/linux/atomic.h +++ b/drivers/gpu/nvgpu/include/nvgpu/linux/atomic.h @@ -81,11 +81,21 @@ static inline bool __nvgpu_atomic_dec_and_test(nvgpu_atomic_t *v) return atomic_dec_and_test(&v->atomic_var); } +static inline bool __nvgpu_atomic_sub_and_test(int i, nvgpu_atomic_t *v) +{ + return atomic_sub_and_test(i, &v->atomic_var); +} + static inline int __nvgpu_atomic_add_return(int i, nvgpu_atomic_t *v) { return atomic_add_return(i, &v->atomic_var); } +static inline int __nvgpu_atomic_add_unless(nvgpu_atomic_t *v, int a, int u) +{ + return atomic_add_unless(&v->atomic_var, a, u); +} + static inline void __nvgpu_atomic64_set(nvgpu_atomic64_t *v, long i) { atomic64_set(&v->atomic_var, i); diff --git a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h index 90261d81..5c0019ae 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h +++ b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h @@ -73,7 +73,7 @@ struct nvgpu_semaphore { nvgpu_atomic_t value; int incremented; - struct kref ref; + struct nvgpu_ref ref; }; /* @@ -106,7 +106,7 @@ struct nvgpu_semaphore_pool { * done waiting on it. This ref count ensures that the pool doesn't * go away until all semaphores using this pool are cleaned up first. */ - struct kref ref; + struct nvgpu_ref ref; }; static inline struct nvgpu_semaphore_pool * diff --git a/drivers/gpu/nvgpu/include/nvgpu/vm.h b/drivers/gpu/nvgpu/include/nvgpu/vm.h index 255b4361..b5c64c99 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/vm.h +++ b/drivers/gpu/nvgpu/include/nvgpu/vm.h @@ -88,7 +88,7 @@ struct nvgpu_mapped_buf { u64 size; struct dma_buf *dmabuf; struct sg_table *sgt; - struct kref ref; + struct nvgpu_ref ref; u32 user_mapped; bool own_mem_ref; u32 pgsz_idx; @@ -142,7 +142,7 @@ struct vm_gk20a { const struct gk20a_mmu_level *mmu_levels; - struct kref ref; + struct nvgpu_ref ref; struct nvgpu_mutex update_gmmu_lock; -- cgit v1.2.2