/** * refcount_set - set a refcount's value * @r: the refcount * @n: value to which the refcount will be set */ staticinlinevoidrefcount_set(refcount_t *r, unsignedint n) { atomic_set(&r->refs, n); }
/** * refcount_read - get a refcount's value * @r: the refcount * * Return: the refcount's value */ staticinlineunsignedintrefcount_read(constrefcount_t *r) { returnatomic_read(&r->refs); }
/** * kref_get_unless_zero - Increment refcount for object unless it is zero. * @kref: object. * * Return non-zero if the increment succeeded. Otherwise return 0. * * This function is intended to simplify locking around refcounting for * objects that can be looked up from a lookup structure, and which are * removed from that lookup structure in the object destructor. * Operations on such objects require at least a read lock around * lookup + kref_get, and a write lock around kref_put + remove from lookup * structure. Furthermore, RCU implementations become extremely tricky. * With a lookup followed by a kref_get_unless_zero *with return value check* * locking in the kref_put path can be deferred to the actual removal from * the lookup structure and RCU lookups become trivial. */ staticinlineint __must_check kref_get_unless_zero(struct kref *kref) { return refcount_inc_not_zero(&kref->refcount); }
kref_put/** * kref_put - 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. If the caller does pass kfree to this * function, you will be publicly mocked mercilessly by the kref * maintainer, and anyone else who happens to notice it. You have * been warned. * * Decrement the refcount, and if 0, call release(). * Return 1 if the object was removed, otherwise return 0. Beware, if this * function returns 0, you still can not count on the kref from remaining in * memory. Only use the return value if you want to see if the kref is now * gone, not present. */ staticinlineintkref_put(struct kref *kref, void (*release)(struct kref *kref)) { if (refcount_dec_and_test(&kref->refcount)) { release(kref); return1; } return0; }
task = kthread_run(more_data_handling, data, "more_data_handling"); if (task == ERR_PTR(-ENOMEM)) { rv = -ENOMEM; goto out; } else/* BAD BAD BAD - get is after the handoff */ kref_get(&data->refcount);