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
