Hi

On Fri, Apr 19, 2013 at 7:24 PM, Greg KH <gre...@linuxfoundation.org> wrote:
> On Fri, Apr 19, 2013 at 06:33:54PM -0700, Anatol Pomozov wrote:
>> Follow-up for https://lkml.org/lkml/2013/4/12/391
>>
>> * make warning smp-safe
>> * result of atomic _unless_zero functions should be checked by caller
>>     to avoid use-after-free error
>>
>> Signed-off-by: Anatol Pomozov <anatol.pomo...@gmail.com>
>> ---
>>  include/linux/kref.h | 9 ++++++---
>>  lib/kobject.c        | 3 ++-
>>  2 files changed, 8 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/linux/kref.h b/include/linux/kref.h
>> index 4972e6e..092529a 100644
>> --- a/include/linux/kref.h
>> +++ b/include/linux/kref.h
>> @@ -39,8 +39,11 @@ static inline void kref_init(struct kref *kref)
>>   */
>>  static inline void kref_get(struct kref *kref)
>>  {
>> -     WARN_ON(!atomic_read(&kref->refcount));
>> -     atomic_inc(&kref->refcount);
>> +     /* If refcount was 0 before incrementing then we have a race
>> +      * condition when this kref is freing by some other thread right now.
>> +      * In this case one should use kref_get_unless_zero()
>> +      */
>> +     WARN_ON(atomic_inc_return(&kref->refcount) < 2);
>
> What happens if you disable WARN_ON(), does the atomic_inc_return() go
> away as well?  Or did we fix that?

If we disable warnings then expression still evaluated, this is true
for BUG_ON as well. It is how the functions are implemented now.

Tejun Heo once mentioned that such behavior is specification of the
functions. So I believe it is safe to execute code inside WARN_ON.

>>  /**
>> @@ -100,7 +103,7 @@ static inline int kref_put_mutex(struct kref *kref,
>>                                struct mutex *lock)
>>  {
>>       WARN_ON(release == NULL);
>> -        if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) {
>> +     if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) {
>>               mutex_lock(lock);
>>               if (unlikely(!atomic_dec_and_test(&kref->refcount))) {
>>                       mutex_unlock(lock);
>> diff --git a/lib/kobject.c b/lib/kobject.c
>> index a654866..bbd7362 100644
>> --- a/lib/kobject.c
>> +++ b/lib/kobject.c
>> @@ -529,7 +529,8 @@ struct kobject *kobject_get(struct kobject *kobj)
>>       return kobj;
>>  }
>>
>> -static struct kobject *kobject_get_unless_zero(struct kobject *kobj)
>> +static struct kobject *__must_check kobject_get_unless_zero(
>> +             struct kobject *kobj)
>
> __must_check needs to be in the .h file, not the .c file.

This function is static and defined in *.c. But I think the function
should be declared in *.h as it might be useful for others. I'll
resend patch tomorrow.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to