On Tue, 6 Feb 2018, Yang Shi wrote:
> +     /*
> +      * Reuse objs from the global free list, they will be reinitialized
> +      * when allocating
> +      */
> +     while (obj_nr_tofree > 0 && (obj_pool_free < obj_pool_min_free)) {
> +             raw_spin_lock_irqsave(&pool_lock, flags);
> +             obj = hlist_entry(obj_to_free.first, typeof(*obj), node);

This is racy vs. the worker thread. Assume obj_nr_tofree = 1:

CPU0                                    CPU1
worker
   lock(&pool_lock);                    while (obj_nr_tofree > 0 && ...) {
     obj = hlist_entry(obj_to_free);      lock(&pool_lock);
     hlist_del(obj);                      
     obj_nr_tofree--;
     ...
   unlock(&pool_lock);
                                          obj = hlist_entry(obj_to_free);
                                          hlist_del(obj); <------- NULL pointer 
dereference

Not what you want, right? The counter or the list head need to be rechecked
after the lock is acquired.

> +             hlist_del(&obj->node);
> +             obj_nr_tofree--;
> +             hlist_add_head(&obj->node, &obj_pool);
> +             obj_pool_free++;
> +             raw_spin_unlock_irqrestore(&pool_lock, flags);
> +     }

Thanks,

        tglx

Reply via email to