All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 10/11] relay - Remove sub-buffers from relay.
@ 2008-09-29  5:40 Tom Zanussi
  0 siblings, 0 replies; only message in thread
From: Tom Zanussi @ 2008-09-29  5:40 UTC (permalink / raw)
  To: Linux Kernel Mailing List
  Cc: Martin Bligh, Peter Zijlstra, prasad, Linus Torvalds,
	Thomas Gleixner, Mathieu Desnoyers, Steven Rostedt, od,
	Frank Ch. Eigler, Andrew Morton, hch, David Wilder

Remove sub-buffers from relay.

This patch removes the concept of sub-buffers from relay - everything
now just operates on pages.  relay_open() was also changed
accordingly; instead of specifying buffer sizes in terms of sub-buffer
sizes and numbers, the buffer size is specfied in pages.  There's also
a new param that specifies how often to wake up consumers, in terms of
every n pages produced.  If 0 is given for this param, consumers are
never woken up.

Signed-off-by: Tom Zanussi <zanussi@comcast.net>

---
 block/blktrace.c      |    7 +-
 include/linux/relay.h |  113 +++++++++++-----------
 kernel/relay.c        |  257 ++++++++++++++++++++++++-------------------------
 virt/kvm/kvm_trace.c  |   25 +++--
 4 files changed, 202 insertions(+), 200 deletions(-)

diff --git a/block/blktrace.c b/block/blktrace.c
index c04168b..84a9cb4 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -359,6 +359,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
 	struct blk_trace *old_bt, *bt = NULL;
 	struct dentry *dir = NULL;
 	int ret, i;
+	int n_pages, n_pages_wakeup;
 
 	if (!buts->buf_size || !buts->buf_nr)
 		return -EINVAL;
@@ -403,8 +404,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
 	if (!bt->msg_file)
 		goto err;
 
-	bt->rchan = relay_open("trace", dir, buts->buf_size,
-			       buts->buf_nr, &blk_relay_callbacks, bt, 0UL);
+	n_pages = (buts->buf_size * buts->buf_nr) / PAGE_SIZE;
+	n_pages_wakeup = buts->buf_size / PAGE_SIZE;
+	bt->rchan = relay_open("trace", dir, n_pages, n_pages_wakeup,
+			       &blk_relay_callbacks, bt, 0UL);
 	if (!bt->rchan)
 		goto err;
 
diff --git a/include/linux/relay.h b/include/linux/relay.h
index dd51caf..e0b1730 100644
--- a/include/linux/relay.h
+++ b/include/linux/relay.h
@@ -19,9 +19,6 @@
 #include <linux/poll.h>
 #include <linux/kref.h>
 
-/* Needs a _much_ better name... */
-#define FIX_SIZE(x) ((((x) - 1) & PAGE_MASK) + PAGE_SIZE)
-
 /*
  * Tracks changes to rchan/rchan_buf structs
  */
@@ -39,10 +36,10 @@
 struct rchan_buf
 {
 	void *start;			/* start of channel buffer */
-	void *data;			/* start of current sub-buffer */
-	size_t offset;			/* current offset into sub-buffer */
-	size_t subbufs_produced;	/* count of sub-buffers produced */
-	size_t subbufs_consumed;	/* count of sub-buffers consumed */
+	void *data;			/* start of current page */
+	size_t offset;			/* current offset into page */
+	size_t produced;		/* count of pages produced */
+	size_t consumed;		/* count of pages consumed */
 	struct rchan *chan;		/* associated channel */
 	wait_queue_head_t read_wait;	/* reader wait queue */
 	struct timer_list timer; 	/* reader wake-up timer */
@@ -51,7 +48,7 @@ struct rchan_buf
 	struct page **page_array;	/* array of current buffer pages */
 	unsigned int page_count;	/* number of current buffer pages */
 	unsigned int finalized;		/* buffer has been finalized */
-	size_t bytes_consumed;		/* bytes consumed in cur read subbuf */
+	size_t consumed_offset;		/* bytes consumed in cur page */
 	size_t early_bytes;		/* bytes consumed before VFS inited */
 	unsigned int cpu;		/* this buf's cpu */
 } ____cacheline_aligned;
@@ -62,13 +59,13 @@ struct rchan_buf
 struct rchan
 {
 	u32 version;			/* the version of this struct */
-	size_t subbuf_size;		/* sub-buffer size */
-	size_t n_subbufs;		/* number of sub-buffers per buffer */
+	size_t n_pages;			/* number of pages per buffer */
+	size_t n_pages_wakeup;		/* wake up readers after filling n */
 	size_t alloc_size;		/* total buffer size allocated */
 	struct rchan_callbacks *cb;	/* client callbacks */
 	struct kref kref;		/* channel refcount */
 	void *private_data;		/* for user-defined data */
-	size_t last_toobig;		/* tried to log event > subbuf size */
+	size_t last_toobig;		/* tried to log event > page size */
 	struct rchan_buf *buf[NR_CPUS]; /* per-cpu channel buffers */
 	struct list_head list;		/* for channel list */
 	struct dentry *parent;		/* parent dentry passed to open */
@@ -84,25 +81,24 @@ struct rchan
 struct rchan_callbacks
 {
 	/*
-	 * new_subbuf - called on buffer-switch to a new sub-buffer
-	 * @buf: the channel buffer containing the new sub-buffer
-	 * @subbuf: the start of the new sub-buffer
+	 * new_page - called on switch to a new page
+	 * @buf: the channel buffer containing the new page
+	 * @page_data: the start of the new page
 	 *
-	 * This is simply a notification that a new sub-buffer has
-	 * been started.  The default version does nothing but call
+	 * This is simply a notification that a new page has been
+	 * switched to.  The default version does nothing but call
 	 * relay_wakeup_readers().  Clients who override this callback
 	 * should also call relay_wakeup_readers() to get that default
 	 * behavior in addition to whatever they add.  Clients who
 	 * don't want to wake up readers should just not call it.
 	 * Clients can use the channel private_data to track previous
-	 * sub-buffers, determine whether this is the first
-	 * sub-buffer, etc.
+	 * pages, determine whether this is the first page, etc.
 	 *
 	 * NOTE: the client can reserve bytes at the beginning of the new
-	 *       sub-buffer by calling subbuf_start_reserve() in this callback.
+	 *       page by calling page_start_reserve() in this callback.
 	 */
-	void (*new_subbuf) (struct rchan_buf *buf,
-			    void *subbuf);
+	void (*new_page) (struct rchan_buf *buf,
+			  void *page_data);
 
 	/*
 	 * buf_mapped - relay buffer mmap notification
@@ -159,7 +155,7 @@ struct rchan_callbacks
 	int (*remove_buf_file)(struct dentry *dentry);
 
 	/*
-	 * switch_subbuf - sub-buffer switch callback
+	 * switch_page - page switch callback
 	 * @buf: the channel buffer
 	 * @length: size of current event
 	 * @reserved: a pointer to the space reserved
@@ -170,12 +166,12 @@ struct rchan_callbacks
 	 *
 	 * Returns either the length passed in or 0 if full.
 	 *
-	 * Performs sub-buffer-switch tasks such as updating filesize,
+	 * Performs page-switch tasks such as updating filesize,
 	 * waking up readers, etc.
 	 */
-	size_t (*switch_subbuf)(struct rchan_buf *buf,
-				size_t length,
-				void **reserved);
+	size_t (*switch_page)(struct rchan_buf *buf,
+			      size_t length,
+			      void **reserved);
 };
 
 /*
@@ -184,8 +180,8 @@ struct rchan_callbacks
 
 struct rchan *relay_open(const char *base_filename,
 			 struct dentry *parent,
-			 size_t subbuf_size,
-			 size_t n_subbufs,
+			 size_t n_pages,
+			 size_t n_pages_wakeup,
 			 struct rchan_callbacks *cb,
 			 void *private_data,
 			 unsigned long rchan_flags);
@@ -194,26 +190,33 @@ extern int relay_late_setup_files(struct rchan *chan,
 				  struct dentry *parent);
 extern void relay_close(struct rchan *chan);
 extern void relay_flush(struct rchan *chan);
-extern void relay_subbufs_consumed(struct rchan *chan,
-				   unsigned int cpu,
-				   size_t consumed);
+extern void relay_pages_consumed(struct rchan *chan,
+				 unsigned int cpu,
+				 size_t consumed);
 extern void relay_reset(struct rchan *chan);
 extern int relay_buf_full(struct rchan_buf *buf);
 
-extern size_t relay_switch_subbuf_default_callback(struct rchan_buf *buf,
-						   size_t length,
-						   void **reserved);
+extern size_t relay_switch_page_default_callback(struct rchan_buf *buf,
+						 size_t length,
+						 void **reserved);
 
 /**
  *	relay_wakeup_readers - wake up readers if applicable
  *	@buf: relay channel buffer
  *
- *	Called by new_subbuf() default implementation, pulled out for
- *	the conveiennce of user-defined new_subbuf() implementations.
+ *	Called by new_page() default implementation, pulled out for
+ *	the convenience of user-defined new_page() implementations.
+ *
+ *	Will wake up readers after each buf->n_pages_wakeup pages have
+ *	been produced.  To do no waking up, simply pass 0 into relay
+ *	open for this value.
  */
 static inline void relay_wakeup_readers(struct rchan_buf *buf)
 {
-	if (waitqueue_active(&buf->read_wait))
+	size_t wakeup = buf->chan->n_pages_wakeup;
+
+	if (wakeup && (buf->produced % wakeup == 0) &&
+	    (waitqueue_active(&buf->read_wait)))
 		/*
 		 * Calling wake_up_interruptible() from here
 		 * will deadlock if we happen to be logging
@@ -224,17 +227,17 @@ static inline void relay_wakeup_readers(struct rchan_buf *buf)
 }
 
 /**
- *	relay_event_toobig - is event too big to fit in a sub-buffer?
+ *	relay_event_toobig - is event too big to fit in a page?
  *	@buf: relay channel buffer
  *	@length: length of event
  *
  *	Returns 1 if too big, 0 otherwise.
  *
- *	switch_subbuf() helper function.
+ *	switch_page() helper function.
  */
 static inline int relay_event_toobig(struct rchan_buf *buf, size_t length)
 {
-	return length > buf->chan->subbuf_size;
+	return length > PAGE_SIZE;
 }
 
 /**
@@ -242,7 +245,7 @@ static inline int relay_event_toobig(struct rchan_buf *buf, size_t length)
  *	@buf: relay channel buffer
  *	@length: length to add
  *
- *	switch_subbuf() helper function.
+ *	switch_page() helper function.
  */
 static inline void relay_update_filesize(struct rchan_buf *buf, size_t length)
 {
@@ -255,14 +258,14 @@ static inline void relay_update_filesize(struct rchan_buf *buf, size_t length)
 }
 
 /**
- *	relay_inc_produced - increase number of sub-buffers produced by 1
+ *	relay_inc_produced - increase number of pages produced by 1
  *	@buf: relay channel buffer
  *
- *	switch_subbuf() helper function.
+ *	switch_page() helper function.
  */
 static inline void relay_inc_produced(struct rchan_buf *buf)
 {
-	buf->subbufs_produced++;
+	buf->produced++;
 }
 
 /**
@@ -290,8 +293,8 @@ static inline void relay_write(struct rchan *chan,
 	local_irq_save(flags);
 	buf = chan->buf[smp_processor_id()];
 	reserved = buf->data + buf->offset;
-	if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
-		remainder = chan->cb->switch_subbuf(buf, length, &reserved);
+	if (unlikely(buf->offset + length > PAGE_SIZE)) {
+		remainder = chan->cb->switch_page(buf, length, &reserved);
 		if (unlikely(!reserved)) {
 			local_irq_restore(flags);
 			return;
@@ -325,8 +328,8 @@ static inline void __relay_write(struct rchan *chan,
 
 	buf = chan->buf[get_cpu()];
 	reserved = buf->data + buf->offset;
-	if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
-		remainder = chan->cb->switch_subbuf(buf, length, &reserved);
+	if (unlikely(buf->offset + length > PAGE_SIZE)) {
+		remainder = chan->cb->switch_page(buf, length, &reserved);
 		if (unlikely(!reserved)) {
 			local_irq_restore(flags);
 			return;
@@ -354,8 +357,8 @@ static inline void *relay_reserve(struct rchan *chan,
 	struct rchan_buf *buf = chan->buf[smp_processor_id()];
 	void *reserved = buf->data + buf->offset;
 
-	if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
-		length = chan->cb->switch_subbuf(buf, length, &reserved);
+	if (unlikely(buf->offset + length > PAGE_SIZE)) {
+		length = chan->cb->switch_page(buf, length, &reserved);
 		if (unlikely(!reserved))
 			return NULL;
 	}
@@ -365,17 +368,17 @@ static inline void *relay_reserve(struct rchan *chan,
 }
 
 /**
- *	subbuf_start_reserve - reserve bytes at the start of a sub-buffer
+ *	page_start_reserve - reserve bytes at the start of a page
  *	@buf: relay channel buffer
  *	@length: number of bytes to reserve
  *
  *	Helper function used to reserve bytes at the beginning of
- *	a sub-buffer in the subbuf_start() callback.
+ *	a page in the new_page() callback.
  */
-static inline void subbuf_start_reserve(struct rchan_buf *buf,
-					size_t length)
+static inline void page_start_reserve(struct rchan_buf *buf,
+				      size_t length)
 {
-	BUG_ON(length >= buf->chan->subbuf_size - 1);
+	BUG_ON(length >= PAGE_SIZE - 1);
 	buf->offset = length;
 }
 
diff --git a/kernel/relay.c b/kernel/relay.c
index 3d06970..137f13f 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -132,31 +132,26 @@ static int relay_mmap_buf(struct rchan_buf *buf, struct vm_area_struct *vma)
 static void *relay_alloc_buf(struct rchan_buf *buf)
 {
 	void *mem;
-	unsigned int i, j, n_pages, n_subbuf_pages;
+	unsigned int i, j;
 
-	buf->chan->alloc_size = PAGE_ALIGN(buf->chan->alloc_size);
-	n_pages = buf->chan->alloc_size >> PAGE_SHIFT;
-	n_subbuf_pages = PAGE_ALIGN(buf->chan->subbuf_size) >> PAGE_SHIFT;
-
-	buf->page_array = relay_alloc_page_array(n_pages + n_subbuf_pages);
+	buf->page_array = relay_alloc_page_array(buf->chan->n_pages + 1);
 	if (!buf->page_array)
 		return NULL;
 
-	for (i = 0; i < n_pages; i++) {
+	for (i = 0; i < buf->chan->n_pages; i++) {
 		buf->page_array[i] = alloc_page(GFP_KERNEL);
 		if (unlikely(!buf->page_array[i]))
 			goto depopulate;
 		set_page_private(buf->page_array[i], (unsigned long)buf);
 	}
-	for (i = 0; i < n_subbuf_pages; i++)
-		buf->page_array[n_pages + i] = buf->page_array[i];
-	mem = vmap(buf->page_array, n_pages + n_subbuf_pages, VM_MAP,
+	buf->page_array[buf->chan->n_pages] = buf->page_array[0];
+	mem = vmap(buf->page_array, buf->chan->n_pages + 1, VM_MAP,
 		   PAGE_KERNEL);
 	if (!mem)
 		goto depopulate;
 
 	memset(mem, 0, buf->chan->alloc_size);
-	buf->page_count = n_pages;
+	buf->page_count = buf->chan->n_pages;
 	return mem;
 
 depopulate:
@@ -247,7 +242,7 @@ static void relay_remove_buf(struct kref *kref)
  */
 static int relay_buf_empty(struct rchan_buf *buf)
 {
-	return (buf->subbufs_produced - buf->subbufs_consumed) ? 0 : 1;
+	return (buf->produced - buf->consumed) ? 0 : 1;
 }
 
 /**
@@ -258,8 +253,8 @@ static int relay_buf_empty(struct rchan_buf *buf)
  */
 int relay_buf_full(struct rchan_buf *buf)
 {
-	size_t ready = buf->subbufs_produced - buf->subbufs_consumed;
-	return (ready >= buf->chan->n_subbufs) ? 1 : 0;
+	size_t ready = buf->produced - buf->consumed;
+	return (ready >= buf->chan->n_pages) ? 1 : 0;
 }
 EXPORT_SYMBOL_GPL(relay_buf_full);
 
@@ -308,22 +303,22 @@ static int remove_buf_file_default_callback(struct dentry *dentry)
 }
 
 /*
- * new_subbuf() default callback.
+ * new_page() default callback.
  */
-static void new_subbuf_default_callback(struct rchan_buf *buf,
-					void *subbuf)
+static void new_page_default_callback(struct rchan_buf *buf,
+				      void *page_data)
 {
 	relay_wakeup_readers(buf);
 }
 
 /* relay channel default callbacks */
 static struct rchan_callbacks default_channel_callbacks = {
-	.new_subbuf = new_subbuf_default_callback,
+	.new_page = new_page_default_callback,
 	.buf_mapped = buf_mapped_default_callback,
 	.buf_unmapped = buf_unmapped_default_callback,
 	.create_buf_file = create_buf_file_default_callback,
 	.remove_buf_file = remove_buf_file_default_callback,
-	.switch_subbuf = relay_switch_subbuf_default_callback,
+	.switch_page = relay_switch_page_default_callback,
 };
 
 /**
@@ -354,14 +349,14 @@ static void __relay_reset(struct rchan_buf *buf, unsigned int init)
 	} else
 		del_timer_sync(&buf->timer);
 
-	buf->subbufs_produced = 0;
-	buf->subbufs_consumed = 0;
-	buf->bytes_consumed = 0;
+	buf->produced = 0;
+	buf->consumed = 0;
+	buf->consumed_offset = 0;
 	buf->finalized = 0;
 	buf->data = buf->start;
 	buf->offset = 0;
 
-	buf->chan->cb->new_subbuf(buf, buf->data);
+	buf->chan->cb->new_page(buf, buf->data);
 }
 
 /**
@@ -493,10 +488,10 @@ static void setup_callbacks(struct rchan *chan,
 		cb->create_buf_file = create_buf_file_default_callback;
 	if (!cb->remove_buf_file)
 		cb->remove_buf_file = remove_buf_file_default_callback;
-	if (!cb->new_subbuf)
-		cb->new_subbuf = new_subbuf_default_callback;
-	if (!cb->switch_subbuf)
-		cb->switch_subbuf = relay_switch_subbuf_default_callback;
+	if (!cb->new_page)
+		cb->new_page = new_page_default_callback;
+	if (!cb->switch_page)
+		cb->switch_page = relay_switch_page_default_callback;
 	chan->cb = cb;
 }
 
@@ -546,8 +541,8 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,
  *	relay_open - create a new relay channel
  *	@base_filename: base name of files to create, %NULL for buffering only
  *	@parent: dentry of parent directory, %NULL for root directory or buffer
- *	@subbuf_size: size of sub-buffers
- *	@n_subbufs: number of sub-buffers
+ *	@n_pages: number of pages to use for each buffer
+ *	@n_pages_wakeup: wakeup readers after this many pages, 0 means never
  *	@cb: client callback functions
  *	@private_data: user-defined data
  *
@@ -560,8 +555,8 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,
  */
 struct rchan *relay_open(const char *base_filename,
 			 struct dentry *parent,
-			 size_t subbuf_size,
-			 size_t n_subbufs,
+			 size_t n_pages,
+			 size_t n_pages_wakeup,
 			 struct rchan_callbacks *cb,
 			 void *private_data,
 			 unsigned long rchan_flags)
@@ -569,7 +564,7 @@ struct rchan *relay_open(const char *base_filename,
 	unsigned int i;
 	struct rchan *chan;
 
-	if (!(subbuf_size && n_subbufs))
+	if (!n_pages)
 		return NULL;
 
 	chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
@@ -577,9 +572,9 @@ struct rchan *relay_open(const char *base_filename,
 		return NULL;
 
 	chan->version = RELAYFS_CHANNEL_VERSION;
-	chan->n_subbufs = n_subbufs;
-	chan->subbuf_size = subbuf_size;
-	chan->alloc_size = FIX_SIZE(subbuf_size * n_subbufs);
+	chan->n_pages = n_pages;
+	chan->n_pages_wakeup = n_pages_wakeup;
+	chan->alloc_size = PAGE_SIZE * n_pages;
 	chan->parent = parent;
 	chan->flags = rchan_flags;
 	atomic_set(&chan->dropped, 0);
@@ -704,57 +699,57 @@ int relay_late_setup_files(struct rchan *chan,
 	return err;
 }
 
-static inline int next_subbuf_free(struct rchan_buf *buf)
+static inline int next_page_free(struct rchan_buf *buf)
 {
-	size_t full_subbufs;
+	size_t full_pages;
 
 	if (buf->chan->flags & RCHAN_MODE_OVERWRITE)
 		return 1;
 
-	full_subbufs = buf->subbufs_produced - buf->subbufs_consumed;
+	full_pages = buf->produced - buf->consumed;
 
-	return (full_subbufs < buf->chan->n_subbufs - 1);
+	return (full_pages < buf->chan->n_pages - 1);
 }
 
 /**
- *	relay_switch_subbuf_default_callback - switch to a new sub-buffer
+ *	relay_switch_page_default_callback - switch to a new page
  *	@buf: channel buffer
  *	@length: size of current event
  *	@reserved: a pointer to the space reserved
  *
  *	Returns either the length passed in or 0 if full.
  *
- *	Performs sub-buffer-switch tasks such as invoking callbacks,
+ *	Performs page-switch tasks such as invoking callbacks,
  *	waking up readers, etc.
  */
-size_t relay_switch_subbuf_default_callback(struct rchan_buf *buf,
-					    size_t length,
-					    void **reserved)
+size_t relay_switch_page_default_callback(struct rchan_buf *buf,
+					  size_t length,
+					  void **reserved)
 {
-	size_t remainder, new_subbuf;
+	size_t remainder, new_page;
 	void *new_data;
 
 	if (unlikely(relay_event_toobig(buf, length)))
 		goto toobig;
 
 	/* don't write anything unless we can write it all. */
-	if (!next_subbuf_free(buf)) {
+	if (!next_page_free(buf)) {
 		if (reserved)
 			*reserved = NULL;
 		atomic_inc(&buf->chan->dropped);
 		return 0;
 	}
 
-	remainder = length - (buf->chan->subbuf_size - buf->offset);
+	remainder = length - (PAGE_SIZE - buf->offset);
 	relay_inc_produced(buf);
-	relay_update_filesize(buf, buf->chan->subbuf_size + remainder);
+	relay_update_filesize(buf, PAGE_SIZE + remainder);
 
-	new_subbuf = buf->subbufs_produced % buf->chan->n_subbufs;
-	new_data = buf->start + new_subbuf * buf->chan->subbuf_size;
+	new_page = buf->produced % buf->chan->n_pages;
+	new_data = buf->start + new_page * PAGE_SIZE;
 
 	buf->data = new_data;
 	buf->offset = 0; /* remainder will be added by caller */
-	buf->chan->cb->new_subbuf(buf, new_data);
+	buf->chan->cb->new_page(buf, new_data);
 
 	if (unlikely(relay_event_toobig(buf, length + buf->offset)))
 		goto toobig;
@@ -764,24 +759,24 @@ toobig:
 	buf->chan->last_toobig = length;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(relay_switch_subbuf_default_callback);
+EXPORT_SYMBOL_GPL(relay_switch_page_default_callback);
 
 /**
- *	relay_subbufs_consumed - update the buffer's sub-buffers-consumed count
+ *	relay_pages_consumed - update the buffer's pages-consumed count
  *	@chan: the channel
  *	@cpu: the cpu associated with the channel buffer to update
- *	@subbufs_consumed: number of sub-buffers to add to current buf's count
+ *	@consumed: number of pages to add to current buf's count
  *
- *	Adds to the channel buffer's consumed sub-buffer count.
- *	subbufs_consumed should be the number of sub-buffers newly consumed,
+ *	Adds to the channel buffer's consumed page count.
+ *	consumed should be the number of pages newly consumed,
  *	not the total consumed.
  *
  *	NOTE. Kernel clients don't need to call this function if the channel
  *	mode is 'overwrite'.
  */
-void relay_subbufs_consumed(struct rchan *chan,
-			    unsigned int cpu,
-			    size_t subbufs_consumed)
+void relay_pages_consumed(struct rchan *chan,
+			  unsigned int cpu,
+			  size_t consumed)
 {
 	struct rchan_buf *buf;
 
@@ -792,11 +787,11 @@ void relay_subbufs_consumed(struct rchan *chan,
 		return;
 
 	buf = chan->buf[cpu];
-	buf->subbufs_consumed += subbufs_consumed;
-	if (buf->subbufs_consumed > buf->subbufs_produced)
-		buf->subbufs_consumed = buf->subbufs_produced;
+	buf->consumed += consumed;
+	if (buf->consumed > buf->produced)
+		buf->consumed = buf->produced;
 }
-EXPORT_SYMBOL_GPL(relay_subbufs_consumed);
+EXPORT_SYMBOL_GPL(relay_pages_consumed);
 
 /**
  *	relay_close - close the channel
@@ -821,8 +816,8 @@ void relay_close(struct rchan *chan)
 
 	if (chan->last_toobig)
 		printk(KERN_WARNING "relay: one or more items not logged "
-		       "[item size (%Zd) > sub-buffer size (%Zd)]\n",
-		       chan->last_toobig, chan->subbuf_size);
+		       "[item size (%Zd) > PAGE_SIZE (%lu)]\n",
+		       chan->last_toobig, PAGE_SIZE);
 
 	list_del(&chan->list);
 	kref_put(&chan->kref, relay_destroy_channel);
@@ -839,20 +834,26 @@ EXPORT_SYMBOL_GPL(relay_close);
 void relay_flush(struct rchan *chan)
 {
 	unsigned int i;
+	size_t prev_wakeup = chan->n_pages_wakeup;
 
 	if (!chan)
 		return;
 
+	if (prev_wakeup)
+		chan->n_pages_wakeup = 1;
+
 	if (chan->flags & RCHAN_GLOBAL_BUFFER && chan->buf[0]) {
-		chan->cb->switch_subbuf(chan->buf[0], 0, NULL);
+		chan->cb->switch_page(chan->buf[0], 0, NULL);
+		chan->n_pages_wakeup = prev_wakeup;
 		return;
 	}
 
 	mutex_lock(&relay_channels_mutex);
 	for_each_possible_cpu(i)
 		if (chan->buf[i])
-			chan->cb->switch_subbuf(chan->buf[i], 0, NULL);
+			chan->cb->switch_page(chan->buf[i], 0, NULL);
 	mutex_unlock(&relay_channels_mutex);
+	chan->n_pages_wakeup = prev_wakeup;
 }
 EXPORT_SYMBOL_GPL(relay_flush);
 
@@ -932,36 +933,36 @@ static void relay_file_read_consume(struct rchan_buf *buf,
 				    size_t read_pos,
 				    size_t bytes_consumed)
 {
-	size_t subbuf_size = buf->chan->subbuf_size;
+	buf->consumed_offset += bytes_consumed;
 
-	buf->bytes_consumed += bytes_consumed;
-
-	if (buf->bytes_consumed == subbuf_size) {
-		relay_subbufs_consumed(buf->chan, buf->cpu, 1);
-		buf->bytes_consumed = 0;
+	if (buf->consumed_offset == PAGE_SIZE) {
+		relay_pages_consumed(buf->chan, buf->cpu, 1);
+		buf->consumed_offset = 0;
 	}
 }
 
 /**
- *	relay_file_read_subbuf_avail - return bytes available in sub-buffer
+ *	relay_file_read_page_avail - return bytes available in page
  *	@read_pos: file read position
  *	@buf: relay channel buffer
  */
-static size_t relay_file_read_subbuf_avail(size_t read_pos,
-					   struct rchan_buf *buf)
+static size_t relay_file_read_page_avail(size_t read_pos,
+					 struct rchan_buf *buf)
 {
 	size_t avail;
-	size_t read_subbuf, read_offset, write_subbuf, write_offset;
-	size_t subbuf_size = buf->chan->subbuf_size;
+	size_t read_page, read_offset, write_page, write_offset;
 
-	write_subbuf = (buf->data - buf->start) / subbuf_size;
+	write_page = (buf->data - buf->start) / PAGE_SIZE;
 	write_offset = buf->offset;
-	read_subbuf = read_pos / subbuf_size;
-	read_offset = read_pos % subbuf_size;
+	read_page = read_pos / PAGE_SIZE;
+	read_offset = read_pos % PAGE_SIZE;
 
-	avail = subbuf_size - read_offset;
+	if (read_page == write_page && read_offset == write_offset)
+		return 0;
 
-	if (read_subbuf == write_subbuf && read_offset < write_offset)
+	avail = PAGE_SIZE - read_offset;
+
+	if (read_page == write_page && read_offset < write_offset)
 		avail = write_offset - read_offset;
 
 	return avail;
@@ -978,11 +979,10 @@ static size_t relay_file_read_subbuf_avail(size_t read_pos,
 static size_t relay_file_read_start_pos(size_t read_pos,
 					struct rchan_buf *buf)
 {
-	size_t subbuf_size = buf->chan->subbuf_size;
-	size_t consumed = buf->subbufs_consumed % buf->chan->n_subbufs;
+	size_t consumed = buf->consumed % buf->chan->n_pages;
 
 	if (!read_pos)
-		read_pos = consumed * subbuf_size + buf->bytes_consumed;
+		read_pos = consumed * PAGE_SIZE + buf->consumed_offset;
 
 	return read_pos;
 }
@@ -999,20 +999,20 @@ static size_t relay_file_read_end_pos(struct rchan_buf *buf,
 {
 	size_t end_pos = read_pos + count;
 
-	if (end_pos >= buf->chan->subbuf_size * buf->chan->n_subbufs)
+	if (end_pos >= PAGE_SIZE * buf->chan->n_pages)
 		end_pos = 0;
 
 	return end_pos;
 }
 
 /*
- *	subbuf_read_actor - read up to one subbuf's worth of data
+ *	page_read_actor - read up to one page's worth of data
  */
-static int subbuf_read_actor(size_t read_start,
-			     struct rchan_buf *buf,
-			     size_t avail,
-			     read_descriptor_t *desc,
-			     read_actor_t actor)
+static int page_read_actor(size_t read_start,
+			   struct rchan_buf *buf,
+			   size_t avail,
+			   read_descriptor_t *desc,
+			   read_actor_t actor)
 {
 	void *from;
 	int ret = 0;
@@ -1030,19 +1030,19 @@ static int subbuf_read_actor(size_t read_start,
 	return ret;
 }
 
-typedef int (*subbuf_actor_t) (size_t read_start,
-			       struct rchan_buf *buf,
-			       size_t avail,
-			       read_descriptor_t *desc,
-			       read_actor_t actor);
+typedef int (*page_actor_t) (size_t read_start,
+			     struct rchan_buf *buf,
+			     size_t avail,
+			     read_descriptor_t *desc,
+			     read_actor_t actor);
 
 /*
- *	relay_file_read_subbufs - read count bytes, bridging subbuf boundaries
+ *	relay_file_read_pages - read count bytes, bridging page boundaries
  */
-static ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos,
-					subbuf_actor_t subbuf_actor,
-					read_actor_t actor,
-					read_descriptor_t *desc)
+static ssize_t relay_file_read_pages(struct file *filp, loff_t *ppos,
+				     page_actor_t page_actor,
+				     read_actor_t actor,
+				     read_descriptor_t *desc)
 {
 	struct rchan_buf *buf = filp->private_data;
 	size_t read_start, avail;
@@ -1054,12 +1054,12 @@ static ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos,
 	mutex_lock(&filp->f_path.dentry->d_inode->i_mutex);
 	do {
 		read_start = relay_file_read_start_pos(*ppos, buf);
-		avail = relay_file_read_subbuf_avail(read_start, buf);
+		avail = relay_file_read_page_avail(read_start, buf);
 		if (!avail)
 			break;
 
 		avail = min(desc->count, avail);
-		ret = subbuf_actor(read_start, buf, avail, desc, actor);
+		ret = page_actor(read_start, buf, avail, desc, actor);
 		if (desc->error < 0)
 			break;
 
@@ -1083,17 +1083,17 @@ static ssize_t relay_file_read(struct file *filp,
 	desc.count = count;
 	desc.arg.buf = buffer;
 	desc.error = 0;
-	return relay_file_read_subbufs(filp, ppos, subbuf_read_actor,
-				       NULL, &desc);
+	return relay_file_read_pages(filp, ppos, page_read_actor,
+				     NULL, &desc);
 }
 
 static void relay_consume_bytes(struct rchan_buf *rbuf, int bytes_consumed)
 {
-	rbuf->bytes_consumed += bytes_consumed;
+	rbuf->consumed_offset += bytes_consumed;
 
-	if (rbuf->bytes_consumed >= rbuf->chan->subbuf_size) {
-		relay_subbufs_consumed(rbuf->chan, rbuf->cpu, 1);
-		rbuf->bytes_consumed %= rbuf->chan->subbuf_size;
+	if (rbuf->consumed_offset >= PAGE_SIZE) {
+		relay_pages_consumed(rbuf->chan, rbuf->cpu, 1);
+		rbuf->consumed_offset %= PAGE_SIZE;
 	}
 }
 
@@ -1121,17 +1121,16 @@ static void relay_page_release(struct splice_pipe_desc *spd, unsigned int i)
 }
 
 /*
- *	subbuf_splice_actor - splice up to one subbuf's worth of data
+ *	page_splice_actor - splice available data
  */
-static int subbuf_splice_actor(struct file *in,
-			       loff_t *ppos,
-			       struct pipe_inode_info *pipe,
-			       size_t len,
-			       unsigned int flags)
+static int page_splice_actor(struct file *in,
+			     loff_t *ppos,
+			     struct pipe_inode_info *pipe,
+			     size_t len,
+			     unsigned int flags)
 {
-	unsigned int pidx, poff, total_len, subbuf_pages, nr_pages, ret;
+	unsigned int pidx, poff, total_len, buf_pages, nr_pages, ret;
 	struct rchan_buf *rbuf = in->private_data;
-	unsigned int subbuf_size = rbuf->chan->subbuf_size;
 	uint64_t pos = (uint64_t) *ppos;
 	uint32_t alloc_size = (uint32_t) rbuf->chan->alloc_size;
 	size_t read_start = (size_t) do_div(pos, alloc_size);
@@ -1146,20 +1145,14 @@ static int subbuf_splice_actor(struct file *in,
 		.spd_release = relay_page_release,
 	};
 
-	if (rbuf->subbufs_produced == rbuf->subbufs_consumed &&
-	    rbuf->offset == rbuf->bytes_consumed)
+	if (rbuf->produced == rbuf->consumed &&
+	    rbuf->offset == rbuf->consumed_offset)
 		return 0;
 
-	/*
-	 * Adjust read len, if longer than what is available
-	 */
-	if (len > (subbuf_size - read_start % subbuf_size))
-		len = subbuf_size - read_start % subbuf_size;
-
-	subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
-	pidx = (read_start / PAGE_SIZE) % subbuf_pages;
+	buf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
+	pidx = (read_start / PAGE_SIZE) % buf_pages;
 	poff = read_start & ~PAGE_MASK;
-	nr_pages = min_t(unsigned int, subbuf_pages, PIPE_BUFFERS);
+	nr_pages = min_t(unsigned int, buf_pages, PIPE_BUFFERS);
 
 	for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) {
 		unsigned int this_len;
@@ -1177,7 +1170,7 @@ static int subbuf_splice_actor(struct file *in,
 		len -= this_len;
 		total_len += this_len;
 		poff = 0;
-		pidx = (pidx + 1) % subbuf_pages;
+		pidx = (pidx + 1) % buf_pages;
 	}
 
 	ret = splice_to_pipe(pipe, &spd);
@@ -1198,7 +1191,7 @@ static ssize_t relay_file_splice_read(struct file *in,
 	spliced = 0;
 
 	while (len && !spliced) {
-		ret = subbuf_splice_actor(in, ppos, pipe, len, flags);
+		ret = page_splice_actor(in, ppos, pipe, len, flags);
 		if (ret < 0)
 			break;
 		else if (!ret) {
diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c
index 293a3c2..9373b34 100644
--- a/virt/kvm/kvm_trace.c
+++ b/virt/kvm/kvm_trace.c
@@ -28,7 +28,7 @@ struct kvm_trace {
 	int trace_state;
 	struct rchan *rchan;
 	struct dentry *lost_file;
-	int first_subbuf;
+	int first_page;
 };
 static struct kvm_trace *kvm_trace;
 
@@ -105,21 +105,21 @@ DEFINE_SIMPLE_ATTRIBUTE(kvm_trace_lost_ops, lost_records_get, NULL, "%llu\n");
  *  many times we encountered a full subbuffer, to tell user space app the
  *  lost records there were.
  */
-static void kvm_new_subbuf_callback(struct rchan_buf *buf,
-				    void *subbuf)
+static void kvm_new_page_callback(struct rchan_buf *buf,
+				  void *page_data)
 {
 	struct kvm_trace *kt = buf->chan->private_data;
 
 	relay_wakeup_readers(buf);
 
-	if (kt->first_subbuf) {
+	if (kt->first_page) {
 		/*
 		 * executed only once when the channel is opened
 		 * save metadata as first record
 		 */
-		subbuf_start_reserve(buf, sizeof(u32));
-		*(u32 *)subbuf = 0x12345678;
-		kt->first_subbuf = 0;
+		page_start_reserve(buf, sizeof(u32));
+		*(u32 *)page_data = 0x12345678;
+		kt->first_page = 0;
 	}
 }
 
@@ -139,7 +139,7 @@ static int kvm_remove_buf_file_callback(struct dentry *dentry)
 }
 
 static struct rchan_callbacks kvm_relay_callbacks = {
-	.new_subbuf		= kvm_new_subbuf_callback,
+	.new_page		= kvm_new_page_callback,
 	.create_buf_file 	= kvm_create_buf_file_callack,
 	.remove_buf_file 	= kvm_remove_buf_file_callback,
 };
@@ -148,6 +148,7 @@ static int do_kvm_trace_enable(struct kvm_user_trace_setup *kuts)
 {
 	struct kvm_trace *kt;
 	int i, r = -ENOMEM;
+	int n_pages, n_pages_wakeup;
 
 	if (!kuts->buf_size || !kuts->buf_nr)
 		return -EINVAL;
@@ -157,14 +158,16 @@ static int do_kvm_trace_enable(struct kvm_user_trace_setup *kuts)
 		goto err;
 
 	r = -EIO;
-	kt->first_subbuf = 1;
+	kt->first_page = 1;
 	kt->lost_file = debugfs_create_file("lost_records", 0444, kvm_debugfs_dir,
 					    kt, &kvm_trace_lost_ops);
 	if (!kt->lost_file)
 		goto err;
 
-	kt->rchan = relay_open("trace", kvm_debugfs_dir, kuts->buf_size,
-			       kuts->buf_nr, &kvm_relay_callbacks, kt, 0UL);
+	n_pages = (kuts->buf_size * kuts->buf_nr) / PAGE_SIZE;
+	n_pages_wakeup = kuts->buf_size / PAGE_SIZE;
+	kt->rchan = relay_open("trace", kvm_debugfs_dir, n_pages,
+			       n_pages_wakeup, &kvm_relay_callbacks, kt, 0UL);
 	if (!kt->rchan)
 		goto err;
 
-- 
1.5.3.5




^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2008-09-29  5:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-29  5:40 [RFC PATCH 10/11] relay - Remove sub-buffers from relay Tom Zanussi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.