lkml.org 
[lkml]   [2013]   [Mar]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: [RFC][PATCH] making vfree() safe from interrupt contexts
From
On Sun, Mar 3, 2013 at 2:51 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> +struct vfree_deferred {
> + spinlock_t lock;
> + void *list;
> + struct work_struct wq;
> +};

Looking more at this, just get rid of the spinlock entirely, and use
<linux/llist.h> for the list.

IRQ-safety without the locking. Because you got the locking wrong
again, and made free_work() use spin_lock_irq(), but

> +static inline void deferred_vfree(void *addr)
> +{
> + struct vfree_deferred *p = &get_cpu_var(vfree_deferred);
> + spin_lock(&p->lock);

This needs to be a spin_lock_irqsave() too.

> + *(void **)addr = p->list;
> + p->list = addr;
> + schedule_work(&p->wq);
> + spin_unlock(&p->lock);
> + put_cpu_var(vfree_deferred);

And there is no reason to hold the lock - or even stay on the CPU -
over the work-scheduling (which had better be irq- and smp-safe on its
own anyway), so you're actually best off just using

struct vfree_deferred *p = &__get_cpu_var(vfree_deferred);
struct llist_node *new = (void *)addr;

llist_add(new, &p->list);
schedule_work(&p->wq);

and you're done.

I'm not even sure it's worth it making it per-cpu, but I guess it
won't hurt either.

Linus


\
 
 \ /
  Last update: 2013-03-04 00:41    [W:0.026 / U:1.924 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site