extend crash command "net" and add a new command "flow"

本文介绍了一次对Crash调试工具的功能增强,新增了'flow'命令,用于调试特定网卡驱动程序。通过该命令可以深入查看网络设备的流量表项,包括流表、组表及规则等详细信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比起Solaris的mdb/kmdb调试功能,Linux下的crash真是弱爆了。首先没有管道功能,其次不能在内核中设置断点。

不过总比没有强。添加了一些功能方便调试我们的网卡驱动程序。


diff--git a/defs.h b/defs.h
index edccdc7..4cb8276 100644
--- a/defs.h
+++ b/defs.h
@@ -4661,6 +4661,7 @@ void cmd_fuser(void);        /* filesys.c */
 void cmd_dev(void);          /* dev.c */
 void cmd_gdb(void);          /* gdb_interface.c */
 void cmd_net(void);          /* net.c */
+void cmd_flow(void);          /* net.c*/
 void cmd_extend(void);       /* extensions.c */
 #if defined(S390) ||defined(S390X)
 void cmd_s390dbf(void);
diff --git a/global_data.c b/global_data.c
index 998aaae..5e291f7 100644
--- a/global_data.c
+++ b/global_data.c
@@ -94,6 +94,7 @@ struct command_table_entry linux_command_table[] = {
       {"mod",     cmd_mod,     help_mod,     0},
       {"mount",   cmd_mount,  help_mount,   0},
       {"net",          cmd_net,  help_net,      REFRESH_TASK_TABLE},
+      {"flow",    cmd_flow,      help_net,      REFRESH_TASK_TABLE},
       {"p",       cmd_p,       help_p,       0},
       {"ps",      cmd_ps,      help_ps,      REFRESH_TASK_TABLE},
       {"pte",     cmd_pte,     help_pte,     0},
diff --git a/net.c b/net.c
index bb86963..df4f48f 100644
--- a/net.c
+++ b/net.c
@@ -20,6 +20,7 @@
 #include <netdb.h>
 #include <net/if_arp.h>
 #include <arpa/inet.h>
+#include <stdlib.h>
 
 /*
  * Cache values we need that can change based on OS version, or anyother
@@ -313,7 +314,8 @@ net_init(void)
  * The net command...
  */
 
-#define NETOPTS       "N:asSR:xdn"
+#define NETOPTS       "N:asSR:xdnl:"
+#define FLOWOPTS  "a:b:"
 #define s_FLAG FOREACH_s_FLAG
 #define S_FLAG FOREACH_S_FLAG
 #define x_FLAG FOREACH_x_FLAG
@@ -329,6 +331,8 @@ net_init(void)
 #define NET_REFERENCE_CHECK(X)   (X)
 #define NET_REFERENCE_FOUND(X)   ((X) && ((X)->cmdflags &NET_REF_FOUND))
 
+char *link_name;
+
 void
 cmd_net(void)
 {
@@ -359,6 +363,10 @@ cmd_net(void)
                     }
                     break;
 
+             case 'l':
+                    link_name = optarg;
+                    break;
+
              case'a':
                     dump_arp();
                     aflag++;
@@ -425,7 +433,7 @@ cmd_net(void)
       if(sflag & (s_FLAG|S_FLAG))
              dump_sockets(sflag,ref);
       else{
-             if ((argcnt == 1) ||nflag)
+             if ((argcnt == 1) || nflag|| link_name)
                     show_net_devices(task);
              elseif (!aflag)
                     cmd_usage(pc->curcmd,SYNOPSIS);
@@ -529,6 +537,39 @@ show_net_devices_v2(ulong task)
       FREEBUF(net_device_buf);
 }
 
+ulong read_pointer(char *name)
+{
+      ulong p, buf[1];
+      p = symbol_value(name);
+
+      readmem(p, KVADDR, buf, sizeof(ulong),name, FAULT_ON_ERROR);
+
+      return buf[0];
+}
+
+ulong read_pointer2(ulong addr, char *type, char *member)
+{
+      int offset;
+      char *buf;
+      ulong val;
+
+      offset = MEMBER_OFFSET(type,member);
+      buf =malloc(offset+sizeof(ulong));
+
+      if (buf == NULL)
+             return 0;
+
+      readmem(addr, KVADDR, buf, offset +sizeof(ulong), "addr", FAULT_ON_ERROR);
+
+      val =  *((ulong *)&buf[offset]);
+      free(buf);
+
+      return val;
+}
+
+ulong mlx5e_priv;
+ulong table_test;
+
 static void
 show_net_devices_v3(ulong task)
 {
@@ -581,10 +622,40 @@ show_net_devices_v3(ulong task)
              get_device_name(ld->list_ptr[i],buf);
              fprintf(fp,"%-6s ", buf);
 
+             if (link_name)
+                    if (strcmp(buf,link_name) == 0)
+                          mlx5e_priv =ld->list_ptr[i] + SIZE(net_device);
+
              get_device_address(ld->list_ptr[i],buf);
              fprintf(fp,"%s\n", buf);
       }
-      
+
+      if (link_name) {
+             fprintf(fp,"\n%s:\n", link_name);
+             fprintf(fp,"mlx5e_priv  %llx\n",mlx5e_priv);
+
+             ulong fs = mlx5e_priv +MEMBER_OFFSET("mlx5e_priv", "fs");
+             fprintf(fp,"mlx5e_flow_steering  %llx\n",fs);
+
+             ulong  ppriv = read_pointer2(mlx5e_priv,"mlx5e_priv", "ppriv");
+             fprintf(fp,"mlx5_eswitch_rep  %llx\n",ppriv);
+
+             ulong  mdev = read_pointer2(mlx5e_priv,"mlx5e_priv", "mdev");
+             fprintf(fp,"mlx5_core_dev  %llx\n",mdev);
+
+             ulong mlx5_priv = mdev +MEMBER_OFFSET("mlx5_core_dev", "priv");
+             fprintf(fp,"mlx5_priv  %llx\n",mlx5_priv);
+
+             ulong esw =  read_pointer2(mlx5_priv,"mlx5_priv", "eswitch");
+             fprintf(fp,"mlx5_eswitch  %llx\n",esw);
+
+             ulong fdb_table = esw +MEMBER_OFFSET("mlx5_eswitch", "fdb_table");
+             fprintf(fp,"mlx5_eswitch_fdb  %llx\n",fdb_table);
+             table_test =read_pointer2(fdb_table, "mlx5_eswitch_fdb", "fdb");
+      }
+
+      link_name = NULL;
+
       FREEBUF(ld->list_ptr);
       FREEBUF(net_device_buf);
 }
@@ -1663,3 +1734,112 @@ sym_socket_dump(ulong file,
 
       returnTRUE;
 }
+
+void
+cmd_flow(void)
+{
+      int c;
+      char *addr;
+      char *ptr;
+      ulong a;
+      struct list_data group,*ld_group;
+      struct list_data fte,*ld_fte;
+      struct list_data rule,*ld_rule;
+      int n1, n2, n3, i1, i2, i3;
+      int show;
+
+      while ((c = getopt(argcnt, args,FLOWOPTS)) != EOF) {
+             switch (c) {
+             case 'a':
+                    show = 1;
+                    addr = optarg;
+                    break;
+             case 'b':
+                    show = 2;
+                    addr = optarg;
+                    break;
+             }
+      }
+
+      a = strtoul(addr, &ptr,16);
+/*    a = table_test; */
+
+      fprintf(fp,"mlx5_flow_table  %llx -x\n",a);
+
+      ld_group =  &group;
+      BZERO(ld_group, sizeof(structlist_data));
+      ld_group->flags |=LIST_ALLOCATE;
+
+      ld_group->start =ld_group->end = a + MEMBER_OFFSET("fs_node","children");
+      ld_group->list_head_offset =0;
+
+      n1 = do_list(ld_group);
+
+      if (show == 1) {
+             for (i1 = 1; i1 < n1;++i1) {
+                    ulong t1 =ld_group->list_ptr[i1];
+                    fprintf(fp,"\tmlx5_flow_group.mask %llx -x\n", t1);
+
+                    ld_fte =  &fte;
+                    BZERO(ld_fte,sizeof(struct list_data));
+                    ld_fte->flags |=LIST_ALLOCATE;
+
+                    ld_fte->start =ld_fte->end = t1 + MEMBER_OFFSET("fs_node","children");
+                    ld_fte->list_head_offset= 0;
+
+                    n2 =do_list(ld_fte);
+                    for (i2 = 1; i2 <n2; ++i2) {
+                          ulong t2 =ld_fte->list_ptr[i2];
+                          fprintf(fp,"\t\tfs_fte.val  %llx -x\n",t2);
+
+                          ld_rule =  &rule;
+                          BZERO(ld_rule,sizeof(struct list_data));
+                          ld_rule->flags|= LIST_ALLOCATE;
+
+                          ld_rule->start= ld_rule->end = t2 + MEMBER_OFFSET("fs_node","children");
+                          ld_rule->list_head_offset= 0;
+
+                          n3 =do_list(ld_rule);
+
+                          for (i3 = 1; i3< n3; ++i3) {
+                                 ulong t3= ld_rule->list_ptr[i3];
+                                 fprintf(fp,"\t\t\tmlx5_flow_rule.dest_attr %llx -x\n", t3);
+                          }
+                    }
+             }
+      } else if (show == 2) {
+             for (i1 = 1; i1 < n1;++i1) {
+                    ulong t1 =ld_group->list_ptr[i1];
+                    fprintf(fp,"\tlist -H %llx -s mlx5_flow_group.mask -x\n",ld_group->list_ptr[0]);
+
+                    ld_fte =  &fte;
+                    BZERO(ld_fte,sizeof(struct list_data));
+                    ld_fte->flags |=LIST_ALLOCATE;
+
+                    ld_fte->start =ld_fte->end = t1 + MEMBER_OFFSET("fs_node","children");
+                    ld_fte->list_head_offset= 0;
+
+                    n2 =do_list(ld_fte);
+                    for (i2 = 1; i2 <n2; ++i2) {
+                          ulong t2 =ld_fte->list_ptr[i2];
+                          fprintf(fp,"\t\tlist -H %llx -s fs_fte.val -x\n", ld_fte->list_ptr[0]);
+
+                          ld_rule =  &rule;
+                          BZERO(ld_rule,sizeof(struct list_data));
+                          ld_rule->flags|= LIST_ALLOCATE;
+
+                          ld_rule->start= ld_rule->end = t2 + MEMBER_OFFSET("fs_node", "children");
+                          ld_rule->list_head_offset= 0;
+
+                          n3 =do_list(ld_rule);
+
+                          ulong t3 =ld_rule->list_ptr[i3];
+                          fprintf(fp,"\t\t\tlist -H %llx -s mlx5_flow_rule.dest_attr -x\n",ld_rule->list_ptr[0]);
+                    }
+             }
+      }
+
+      FREEBUF(ld_group->list_ptr);
+      FREEBUF(ld_fte->list_ptr);
+      FREEBUF(ld_rule->list_ptr);
+}


  crash> net -l p2p1
   NET_DEVICE     NAME   IP ADDRESS(ES)
ffff880c66c79000  lo     127.0.0.1
ffff8806615fc000  em1    10.200.0.168
ffff880660c78000  em2
ffff88056200a000  virbr0 192.168.122.1
ffff880562978000  virbr0-nic
ffff88055e16d000  ovs-system
ffff880c016d0000  p4p1
ffff8805fcdd0000  p4p2
ffff88039aa30000  p2p1
ffff88039b430000  p2p2
ffff8803a2d20000  p7p1
ffff880c4fbf0000  p7p2
ffff8803a11f0000  p2p1_0
ffff8805af9a0000  p2p1_1
ffff880c60507000  br0
ffff880610d8c000  vnet0
ffff880c1779c000  vnet1

p2p1:
mlx5e_priv  ffff88039aa308c0
mlx5e_flow_steering  ffff88039aa32eb0
mlx5_eswitch_rep  ffff88065f60fc00
mlx5_core_dev  ffff8806325c0060
mlx5_priv  ffff8806325f60d8
mlx5_eswitch  ffff88055ed2a000
mlx5_eswitch_fdb  ffff88055ed2a818
crash> mlx5_eswitch_fdb  ffff88055ed2a818
struct mlx5_eswitch_fdb {
  fdb = 0xffff880b4966fe00,
  {
    legacy = {
      addr_grp = 0xffff8805d355a700,
      allmulti_grp = 0xffff880666d44c00,
      promisc_grp = 0xffff880666d41000
    },
    offloads = {
      fdb = 0xffff8805d355a700,
      send_to_vport_grp = 0xffff880666d44c00,
      miss_grp = 0xffff880666d41000,
      miss_rule = 0xffff88060e5face0,
      vlan_push_pop_refcount = 0x4
    }
  }
}
crash> flow -a 0xffff880b4966fe00
mlx5_flow_table  ffff880b4966fe00 -x
        mlx5_flow_group.mask ffff880666d40800 -x
                fs_fte.val,index  ffff880666d41800 -x
                        mlx5_flow_rule.dest_attr ffff8805e28ffd40 -x
                        mlx5_flow_rule.dest_attr ffff8805e28ff8c0 -x
                fs_fte.val,index  ffff880614090000 -x
                        mlx5_flow_rule.dest_attr ffff88065fbd0d80 -x
                        mlx5_flow_rule.dest_attr ffff88065fbd0fc0 -x
        mlx5_flow_group.mask ffff880614097000 -x
                fs_fte.val,index  ffff880614091c00 -x
                        mlx5_flow_rule.dest_attr ffff88065fbd15c0 -x
                        mlx5_flow_rule.dest_attr ffff88065fbd1b00 -x
                fs_fte.val,index  ffff8806666afc00 -x
                        mlx5_flow_rule.dest_attr ffff880c66c12cc0 -x
                        mlx5_flow_rule.dest_attr ffff880c66c12d80 -x
crash> flow -b 0xffff880b4966fe00
mlx5_flow_table  ffff880b4966fe00 -x
        list -H ffff880b4966fe10 -s mlx5_flow_group.mask -x
                list -H ffff880666d40810 -s fs_fte.val,index -x
                        list -H ffff880666d41810 -s mlx5_flow_rule.dest_attr -x
                list -H ffff880666d40810 -s fs_fte.val,index -x
                        list -H ffff880614090010 -s mlx5_flow_rule.dest_attr -x
        list -H ffff880b4966fe10 -s mlx5_flow_group.mask -x
                list -H ffff880614097010 -s fs_fte.val,index -x
                        list -H ffff880614091c10 -s mlx5_flow_rule.dest_attr -x
                list -H ffff880614097010 -s fs_fte.val,index -x
                        list -H ffff8806666afc10 -s mlx5_flow_rule.dest_attr -x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值