public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Lai Jiangshan <laijs@cn.fujitsu.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>,
	David Miller <davem@davemloft.net>,
	Dave Airlie <airlied@gmail.com>, Paul Menage <menage@google.com>,
	kamezawa.hiroyu@jp.fujitsu.com,
	Balbir Singh <balbir@linux.vnet.ibm.com>,
	Arjan van de Ven <arjan@infradead.org>, Jan Kara <jack@suse.cz>,
	Jes Sorensen <jes@sgi.com>,
	KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
	dada1@cosmosbay.com, Alexey Dobriyan <adobriyan@gmail.com>,
	Jens Axboe <jens.axboe@oracle.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Nick Piggin <npiggin@suse.de>, Al Viro <viro@zeniv.linux.org.uk>,
	Rik van Riel <riel@redhat.com>,
	Pekka Enberg <penberg@cs.helsinki.fi>
Subject: [PATCH V2 4/4] sysipc: use kvmalloc()/kvfree_atomic()
Date: Tue, 18 Nov 2008 16:51:25 +0800	[thread overview]
Message-ID: <4922820D.4000802@cn.fujitsu.com> (raw)
In-Reply-To: <20081117131440.GB29931@cmpxchg.org>


RCU callback here use vfree()
use kvmalloc()/kvfree_atomic() make it simple


Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
 util.c |  116 ++++++++++-------------------------------------------------------
 1 file changed, 19 insertions(+), 97 deletions(-)
diff --git a/ipc/util.c b/ipc/util.c
index 49b3ea6..3ecf04d 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -468,51 +468,16 @@ void ipc_free(void* ptr, int size)
 		kfree(ptr);
 }
 
-/*
- * rcu allocations:
- * There are three headers that are prepended to the actual allocation:
- * - during use: ipc_rcu_hdr.
- * - during the rcu grace period: ipc_rcu_grace.
- * - [only if vmalloc]: ipc_rcu_sched.
- * Their lifetime doesn't overlap, thus the headers share the same memory.
- * Unlike a normal union, they are right-aligned, thus some container_of
- * forward/backward casting is necessary:
- */
 struct ipc_rcu_hdr
 {
-	int refcount;
-	int is_vmalloc;
-	void *data[0];
-};
-
-
-struct ipc_rcu_grace
-{
-	struct rcu_head rcu;
+	union {
+		int refcount;
+		struct rcu_head rcu;
+	};
 	/* "void *" makes sure alignment of following data is sane. */
 	void *data[0];
 };
 
-struct ipc_rcu_sched
-{
-	struct work_struct work;
-	/* "void *" makes sure alignment of following data is sane. */
-	void *data[0];
-};
-
-#define HDRLEN_KMALLOC		(sizeof(struct ipc_rcu_grace) > sizeof(struct ipc_rcu_hdr) ? \
-					sizeof(struct ipc_rcu_grace) : sizeof(struct ipc_rcu_hdr))
-#define HDRLEN_VMALLOC		(sizeof(struct ipc_rcu_sched) > HDRLEN_KMALLOC ? \
-					sizeof(struct ipc_rcu_sched) : HDRLEN_KMALLOC)
-
-static inline int rcu_use_vmalloc(int size)
-{
-	/* Too big for a single page? */
-	if (HDRLEN_KMALLOC + size > PAGE_SIZE)
-		return 1;
-	return 0;
-}
-
 /**
  *	ipc_rcu_alloc	-	allocate ipc and rcu space 
  *	@size: size desired
@@ -522,30 +487,18 @@ static inline int rcu_use_vmalloc(int size)
  *	NULL is returned if the allocation fails. 
  */
  
-void* ipc_rcu_alloc(int size)
+void *ipc_rcu_alloc(int size)
 {
-	void* out;
 	/* 
-	 * We prepend the allocation with the rcu struct, and
-	 * workqueue if necessary (for vmalloc). 
+	 * We prepend the allocation with the ipc_rcu_hdr
 	 */
-	if (rcu_use_vmalloc(size)) {
-		out = vmalloc(HDRLEN_VMALLOC + size);
-		if (out) {
-			out += HDRLEN_VMALLOC;
-			container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 1;
-			container_of(out, struct ipc_rcu_hdr, data)->refcount = 1;
-		}
-	} else {
-		out = kmalloc(HDRLEN_KMALLOC + size, GFP_KERNEL);
-		if (out) {
-			out += HDRLEN_KMALLOC;
-			container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 0;
-			container_of(out, struct ipc_rcu_hdr, data)->refcount = 1;
-		}
-	}
+	struct ipc_rcu_hdr *hdr = kvmalloc(sizeof(struct ipc_rcu_hdr) + size,
+			GFP_KERNEL);
+	if (!hdr)
+		return NULL;
 
-	return out;
+	hdr->refcount = 1;
+	return hdr->data;
 }
 
 void ipc_rcu_getref(void *ptr)
@@ -553,56 +506,25 @@ void ipc_rcu_getref(void *ptr)
 	container_of(ptr, struct ipc_rcu_hdr, data)->refcount++;
 }
 
-static void ipc_do_vfree(struct work_struct *work)
-{
-	vfree(container_of(work, struct ipc_rcu_sched, work));
-}
-
 /**
- * ipc_schedule_free - free ipc + rcu space
+ * ipc_free_rcu - free ipc + ipc_rcu_hdr
  * @head: RCU callback structure for queued work
  * 
  * Since RCU callback function is called in bh,
- * we need to defer the vfree to schedule_work().
- */
-static void ipc_schedule_free(struct rcu_head *head)
-{
-	struct ipc_rcu_grace *grace;
-	struct ipc_rcu_sched *sched;
-
-	grace = container_of(head, struct ipc_rcu_grace, rcu);
-	sched = container_of(&(grace->data[0]), struct ipc_rcu_sched,
-				data[0]);
-
-	INIT_WORK(&sched->work, ipc_do_vfree);
-	schedule_work(&sched->work);
-}
-
-/**
- * ipc_immediate_free - free ipc + rcu space
- * @head: RCU callback structure that contains pointer to be freed
- *
- * Free from the RCU callback context.
+ * we need to use kvfree_atomic().
  */
-static void ipc_immediate_free(struct rcu_head *head)
+static void ipc_free_rcu(struct rcu_head *head)
 {
-	struct ipc_rcu_grace *free =
-		container_of(head, struct ipc_rcu_grace, rcu);
-	kfree(free);
+	kvfree_atomic(container_of(head, struct ipc_rcu_hdr, rcu));
 }
 
 void ipc_rcu_putref(void *ptr)
 {
-	if (--container_of(ptr, struct ipc_rcu_hdr, data)->refcount > 0)
+	struct ipc_rcu_hdr *hdr = container_of(ptr, struct ipc_rcu_hdr, data);
+	if (--hdr->refcount > 0)
 		return;
 
-	if (container_of(ptr, struct ipc_rcu_hdr, data)->is_vmalloc) {
-		call_rcu(&container_of(ptr, struct ipc_rcu_grace, data)->rcu,
-				ipc_schedule_free);
-	} else {
-		call_rcu(&container_of(ptr, struct ipc_rcu_grace, data)->rcu,
-				ipc_immediate_free);
-	}
+	call_rcu(&hdr->rcu, ipc_free_rcu);
 }
 
 /**



  parent reply	other threads:[~2008-11-18  8:55 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-17 12:26 [PATCH V2 1/1] mm: introduce kvmalloc()/kvfree() Lai Jiangshan
2008-11-17 13:14 ` Johannes Weiner
2008-11-18  0:28   ` Lai Jiangshan
2008-11-18  8:50   ` [PATCH V2 0/4] use kvmalloc()/kvfree() the second part, about RCU Lai Jiangshan
2008-11-18  8:51   ` [PATCH V2 1/4] vmalloc: introduce vfree_atomic() Lai Jiangshan
2008-11-18  9:19     ` Nick Piggin
2008-11-18 11:38       ` Lai Jiangshan
2008-11-18 12:05         ` Nick Piggin
2008-11-18  8:51   ` [PATCH V2 2/4] mm: introduce kvfree_atomic() Lai Jiangshan
2008-11-18  8:51   ` [PATCH V2 3/4] files: use kvmalloc()/kvfree()/kvfree_atomic() Lai Jiangshan
2008-11-18  8:51   ` Lai Jiangshan [this message]
2008-11-18  6:57 ` [PATCH V2 1/1] mm: introduce kvmalloc()/kvfree() Pekka Enberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4922820D.4000802@cn.fujitsu.com \
    --to=laijs@cn.fujitsu.com \
    --cc=adobriyan@gmail.com \
    --cc=airlied@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=arjan@infradead.org \
    --cc=balbir@linux.vnet.ibm.com \
    --cc=dada1@cosmosbay.com \
    --cc=davem@davemloft.net \
    --cc=hannes@cmpxchg.org \
    --cc=jack@suse.cz \
    --cc=jens.axboe@oracle.com \
    --cc=jes@sgi.com \
    --cc=kamezawa.hiroyu@jp.fujitsu.com \
    --cc=kosaki.motohiro@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=menage@google.com \
    --cc=npiggin@suse.de \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=penberg@cs.helsinki.fi \
    --cc=riel@redhat.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox