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
