From: Tang Longjun <[email protected]>

introduce kfifo buffers to support more frequent log output
or file writing

Signed-off-by: Tang Longjun <[email protected]>
---
 tools/virtio/virtnet_mon/virtnet_mon.c | 57 ++++++++++++++++++--------
 1 file changed, 39 insertions(+), 18 deletions(-)

diff --git a/tools/virtio/virtnet_mon/virtnet_mon.c 
b/tools/virtio/virtnet_mon/virtnet_mon.c
index 6e768ea5e28d..696e621cf803 100644
--- a/tools/virtio/virtnet_mon/virtnet_mon.c
+++ b/tools/virtio/virtnet_mon/virtnet_mon.c
@@ -6,16 +6,14 @@
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
 #include <linux/poll.h>
-#include <linux/string.h>
-#include <linux/if_ether.h>
-
 
 #define DEVICE_NAME "virtnet_mon"
+#define KFIFO_SIZE 1024     // ring buffer size
 
+static DEFINE_KFIFO(virtnet_mon_kfifo, char, KFIFO_SIZE);
 static struct miscdevice virtnet_mon_misc_device;
 
-static char buf[1024];
-static int buf_len;
+static DECLARE_WAIT_QUEUE_HEAD(virtnet_mon_wq);
 
 // open device
 static int virtnet_mon_open(struct inode *inode, struct file *file)
@@ -34,33 +32,56 @@ static int virtnet_mon_release(struct inode *inode, struct 
file *file)
 // read device
 static ssize_t virtnet_mon_read(struct file *file, char __user *buffer, size_t 
len, loff_t *offset)
 {
-       len = buf_len;
-       if (copy_to_user(buffer, buf, buf_len))
+       unsigned int copied;
+       char kfifo_buffer[KFIFO_SIZE];
+
+       // read data from kfifo
+       if (kfifo_is_empty(&virtnet_mon_kfifo))
+               return 0;
+
+       // read data and copy to user space
+       copied = kfifo_out(&virtnet_mon_kfifo, kfifo_buffer, len);
+       if (copy_to_user(buffer, kfifo_buffer, copied))
                return -EFAULT;
 
-       buf_len = 0;
-       memset(buf, 0, sizeof(buf));
-       return len;
+       //pr_debug(KERN_INFO "virtnet_mon: Read %u bytes from kfifo\n", copied);
+
+       return copied;
 }
 
 // write device
 static ssize_t virtnet_mon_write(struct file *file, const char __user *buffer,
                                                        size_t len, loff_t 
*offset)
 {
-       memset(buf, 0, sizeof(buf));
-       if (copy_from_user(buf, buffer, len))
+       unsigned int copied;
+       char kfifo_buffer[KFIFO_SIZE];
+
+       // copy data from user space to kfifo
+       if (len > KFIFO_SIZE)
+               len = KFIFO_SIZE;
+
+       if (copy_from_user(kfifo_buffer, buffer, len))
                return -EFAULT;
 
-       buf_len = len;
-       pr_info("virtnet_mon: Written: %s\n", buf);
+       copied = kfifo_in(&virtnet_mon_kfifo, kfifo_buffer, len);
+       pr_info("virtnet_mon: Written %u bytes to kfifo\n", copied);
+
+       wake_up_interruptible(&virtnet_mon_wq);
 
-       return len;
+       return copied;
 }
 
 // poll method
 static unsigned int virtnet_mon_poll(struct file *file, poll_table *wait)
 {
-       return 0;
+       unsigned int mask = 0;
+
+       poll_wait(file, &virtnet_mon_wq, wait);
+
+       if (!kfifo_is_empty(&virtnet_mon_kfifo))
+               mask |= POLLIN | POLLRDNORM;
+
+       return mask;
 }
 
 // file operations structure
@@ -89,8 +110,8 @@ static int __init virtnet_mon_init(void)
 
                return ret;
        }
-       pr_info("virtnet_mon registered with minor number %d\n", 
virtnet_mon_misc_device.minor);
 
+       pr_info("virtnet_mon registered with minor number %d\n", 
virtnet_mon_misc_device.minor);
        return 0;
 }
 
@@ -107,4 +128,4 @@ module_exit(virtnet_mon_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tang Longjun");
 MODULE_DESCRIPTION("Monitor virtio_net driver packet transmission and 
reception");
-MODULE_VERSION("0.1");
+MODULE_VERSION("0.2");
-- 
2.43.0


Reply via email to