From: Tang Longjun <[email protected]>

track the timestamp when packets enter the network stack using
the kprobe on the gro_receive_skb function

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

diff --git a/tools/virtio/virtnet_mon/virtnet_mon.c 
b/tools/virtio/virtnet_mon/virtnet_mon.c
index 36b51d0a13d4..9c0b5ebc3f03 100644
--- a/tools/virtio/virtnet_mon/virtnet_mon.c
+++ b/tools/virtio/virtnet_mon/virtnet_mon.c
@@ -438,6 +438,8 @@ enum pkt_dir {
 enum event_type {
        START_XMIT_PRE_EVENT = 1,
        START_XMIT_POST_EVENT = 2,
+       GRO_RECEIVE_SKB_PRE_EVENT = 3,
+       GRO_RECEIVE_SKB_POST_EVENT = 4,
 };
 
 struct iph_info {
@@ -479,6 +481,7 @@ static DECLARE_WAIT_QUEUE_HEAD(virtnet_mon_wq);
 static char read_buf[READ_SIZE];
 
 static struct kprobe start_xmit_kp;
+static struct kprobe gro_receive_skb_kp;
 
 /* convert pkt_dir to string */
 static const char *pkt_dir_to_str(enum pkt_dir dir)
@@ -516,6 +519,10 @@ static const char *event_type_to_str(enum event_type 
event_type)
                return "START_XMIT_PRE_EVENT";
        case START_XMIT_POST_EVENT:
                return "START_XMIT_POST_EVENT";
+       case GRO_RECEIVE_SKB_PRE_EVENT:
+               return "GRO_RECEIVE_SKB_PRE_EVENT";
+       case GRO_RECEIVE_SKB_POST_EVENT:
+                       return "GRO_RECEIVE_SKB_POST_EVENT";
        default:
                return "Unknown";
        }
@@ -724,6 +731,32 @@ static int start_xmit_pre_handler(struct kprobe *p, struct 
pt_regs *regs)
        return 0;
 }
 
+/* Kprobe pre-handler for gro_receive_skb */
+static int gro_receive_skb_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+       struct sk_buff *skb;
+       struct virtnet_mon_pkt_info info;
+       struct _virtnet_info *vi;
+       int qnum;
+
+       /* Get skb parameter (second parameter) */
+       skb = (struct sk_buff *)KP_GET_ARG(regs, 1);
+
+       memset(&info, 0, sizeof(struct virtnet_mon_pkt_info));
+       get_common_info(PKT_DIR_RX, GRO_RECEIVE_SKB_PRE_EVENT, &info);
+
+       vi = netdev_priv(skb->dev);
+       qnum = skb_get_rx_queue(skb);
+
+       if (get_queue_info(vi->rq[qnum].vq, &info.rx_tx_queue_info) != 0)
+               return 0;
+
+       kfifo_in(&virtnet_mon_kfifo, &info, 1);
+       wake_up_interruptible(&virtnet_mon_wq);
+
+       return 0;
+}
+
 // open device
 static int virtnet_mon_open(struct inode *inode, struct file *file)
 {
@@ -859,6 +892,18 @@ static int __init virtnet_mon_init(void)
        }
        pr_info("virtnet_mon: Registered kprobe for start_xmit\n");
 
+       /* Setup kprobe for gro_receive_skb */
+       gro_receive_skb_kp.pre_handler = gro_receive_skb_pre_handler;
+       gro_receive_skb_kp.symbol_name = "gro_receive_skb";
+
+       ret = register_kprobe(&gro_receive_skb_kp);
+       if (ret < 0) {
+               pr_info("virtnet_mon: Failed to register kprobe for 
gro_receive_skb: %d\n", ret);
+               unregister_kprobe(&gro_receive_skb_kp);
+               return ret;
+       }
+       pr_info("virtnet_mon: Registered kprobe for gro_receive_skb\n");
+
        return 0;
 }
 
@@ -870,6 +915,7 @@ static void __exit virtnet_mon_exit(void)
 
        /* Unregister kprobes */
        unregister_kprobe(&start_xmit_kp);
+       unregister_kprobe(&gro_receive_skb_kp);
        pr_info("virtnet_mon: Unloading module\n");
 }
 
-- 
2.43.0


Reply via email to