lkml.org 
[lkml]   [2002]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    SubjectRe: [PATCH]updated ipc lock patch
    Date
    > diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.44-mm4-ipc-rcu/include/linux/msg.h working-2.5.44-mm4-ipc-rcu-fix/include/linux/msg.h
    > --- working-2.5.44-mm4-ipc-rcu/include/linux/msg.h 2002-07-21 17:43:10.000000000 +1000
    > +++ working-2.5.44-mm4-ipc-rcu-fix/include/linux/msg.h 2002-10-28 11:12:54.000000000 +1100

    Oops. That patch had some fluff in msg.h and sem.h. Delete those, or
    just use this instead (still against Mingming's mm4 "ignore kmalloc
    failure" patch):

    diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.44-mm4-ipc-rcu/ipc/util.c working-2.5.44-mm4-ipc-rcu-fix/ipc/util.c
    --- working-2.5.44-mm4-ipc-rcu/ipc/util.c 2002-10-28 11:08:35.000000000 +1100
    +++ working-2.5.44-mm4-ipc-rcu-fix/ipc/util.c 2002-10-28 12:01:09.000000000 +1100
    @@ -213,21 +213,49 @@ struct kern_ipc_perm* ipc_rmid(struct ip
    return p;
    }

    +struct ipc_rcu_kmalloc
    +{
    + struct rcu_head rcu;
    + /* "void *" makes sure alignment of following data is sane. */
    + void *data[0];
    +};
    +
    +struct ipc_rcu_vmalloc
    +{
    + struct rcu_head rcu;
    + struct work_struct work;
    + /* "void *" makes sure alignment of following data is sane. */
    + void *data[0];
    +};
    +
    +static inline int use_vmalloc(int size)
    +{
    + /* Too big for a single page? */
    + if (sizeof(struct ipc_rcu_kmalloc) + size > PAGE_SIZE)
    + return 1;
    + return 0;
    +}
    +
    /**
    * ipc_alloc - allocate ipc space
    * @size: size desired
    *
    * Allocate memory from the appropriate pools and return a pointer to it.
    - * NULL is returned if the allocation fails
    + * NULL is returned if the allocation fails. This can be freed with
    + * ipc_free (to free immediately) or ipc_rcu_free (to free once safe).
    */
    -
    void* ipc_alloc(int size)
    {
    void* out;
    - if(size > PAGE_SIZE)
    - out = vmalloc(size);
    - else
    - out = kmalloc(size, GFP_KERNEL);
    + /* We prepend the allocation with the rcu struct, and
    + workqueue if necessary (for vmalloc). */
    + if (use_vmalloc(size)) {
    + out = vmalloc(sizeof(struct ipc_rcu_vmalloc) + size);
    + if (out) out += sizeof(struct ipc_rcu_vmalloc);
    + } else {
    + out = kmalloc(sizeof(struct ipc_rcu_kmalloc)+size, GFP_KERNEL);
    + if (out) out += sizeof(struct ipc_rcu_kmalloc);
    + }
    return out;
    }

    @@ -242,48 +270,36 @@ void* ipc_alloc(int size)

    void ipc_free(void* ptr, int size)
    {
    - if(size > PAGE_SIZE)
    - vfree(ptr);
    + if (use_vmalloc(size))
    + vfree(ptr - sizeof(struct ipc_rcu_vmalloc));
    else
    - kfree(ptr);
    + kfree(ptr - sizeof(struct ipc_rcu_kmalloc));
    }

    /*
    * Since RCU callback function is called in bh,
    * we need to defer the vfree to schedule_work
    */
    -static void ipc_free_scheduled(void* arg)
    +static void ipc_schedule_free(void *arg)
    {
    - struct rcu_ipc_free *a = (struct rcu_ipc_free *)arg;
    - vfree(a->ptr);
    - kfree(a);
    -}
    + struct ipc_rcu_vmalloc *free = arg;

    -static void ipc_free_callback(void* arg)
    -{
    - struct rcu_ipc_free *a = (struct rcu_ipc_free *)arg;
    - /*
    - * if data is vmalloced, then we need to delay the free
    - */
    - if (a->size > PAGE_SIZE) {
    - INIT_WORK(&a->work, ipc_free_scheduled, arg);
    - schedule_work(&a->work);
    - } else {
    - kfree(a->ptr);
    - kfree(a);
    - }
    + INIT_WORK(&free->work, vfree, free);
    + schedule_work(&free->work);
    }

    void ipc_rcu_free(void* ptr, int size)
    {
    - struct rcu_ipc_free* arg;
    -
    - arg = (struct rcu_ipc_free *) kmalloc(sizeof(*arg), GFP_KERNEL);
    - if (arg == NULL)
    - return;
    - arg->ptr = ptr;
    - arg->size = size;
    - call_rcu(&arg->rcu_head, ipc_free_callback, arg);
    + if (use_vmalloc(size)) {
    + struct ipc_rcu_vmalloc *free;
    + free = ptr - sizeof(*free);
    + call_rcu(&free->rcu, ipc_schedule_free, free);
    + } else {
    + struct ipc_rcu_kmalloc *free;
    + free = ptr - sizeof(*free);
    + /* kfree takes a "const void *" so gcc warns. So we cast. */
    + call_rcu(&free->rcu, (void (*)(void *))kfree, free);
    + }
    }

    /**
    --
    Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:30    [W:0.024 / U:3.792 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site