Loading drivers/usb/gadget/function/f_diag.c +32 −0 Original line number Original line Diff line number Diff line Loading @@ -206,6 +206,38 @@ static inline struct diag_context *func_to_diag(struct usb_function *f) return container_of(f, struct diag_context, function); return container_of(f, struct diag_context, function); } } /** * kref_put_spinlock_irqsave - decrement refcount for object. * @kref: object. * @release: pointer to the function that will clean up the object when the * last reference to the object is released. * This pointer is required, and it is not acceptable to pass kfree * in as this function. * @lock: lock to take in release case * * Behaves identical to kref_put with one exception. If the reference count * drops to zero, the lock will be taken atomically wrt dropping the reference * count. The release function has to call spin_unlock() without _irqrestore. */ static inline int kref_put_spinlock_irqsave(struct kref *kref, void (*release)(struct kref *kref), spinlock_t *lock) { unsigned long flags; WARN_ON(release == NULL); if (atomic_add_unless(&kref->refcount, -1, 1)) return 0; spin_lock_irqsave(lock, flags); if (atomic_dec_and_test(&kref->refcount)) { release(kref); local_irq_restore(flags); return 1; } spin_unlock_irqrestore(lock, flags); return 0; } /* Called with ctxt->lock held; i.e. only use with kref_put_spinlock_irqsave */ /* Called with ctxt->lock held; i.e. only use with kref_put_spinlock_irqsave */ static void diag_context_release(struct kref *kref) static void diag_context_release(struct kref *kref) { { Loading Loading
drivers/usb/gadget/function/f_diag.c +32 −0 Original line number Original line Diff line number Diff line Loading @@ -206,6 +206,38 @@ static inline struct diag_context *func_to_diag(struct usb_function *f) return container_of(f, struct diag_context, function); return container_of(f, struct diag_context, function); } } /** * kref_put_spinlock_irqsave - decrement refcount for object. * @kref: object. * @release: pointer to the function that will clean up the object when the * last reference to the object is released. * This pointer is required, and it is not acceptable to pass kfree * in as this function. * @lock: lock to take in release case * * Behaves identical to kref_put with one exception. If the reference count * drops to zero, the lock will be taken atomically wrt dropping the reference * count. The release function has to call spin_unlock() without _irqrestore. */ static inline int kref_put_spinlock_irqsave(struct kref *kref, void (*release)(struct kref *kref), spinlock_t *lock) { unsigned long flags; WARN_ON(release == NULL); if (atomic_add_unless(&kref->refcount, -1, 1)) return 0; spin_lock_irqsave(lock, flags); if (atomic_dec_and_test(&kref->refcount)) { release(kref); local_irq_restore(flags); return 1; } spin_unlock_irqrestore(lock, flags); return 0; } /* Called with ctxt->lock held; i.e. only use with kref_put_spinlock_irqsave */ /* Called with ctxt->lock held; i.e. only use with kref_put_spinlock_irqsave */ static void diag_context_release(struct kref *kref) static void diag_context_release(struct kref *kref) { { Loading