0001 .. SPDX-License-Identifier: GPL-2.0
0002
0003 =======================================
0004 QLogic QLGE 10Gb Ethernet device driver
0005 =======================================
0006
0007 This driver use drgn and devlink for debugging.
0008
0009 Dump kernel data structures in drgn
0010 -----------------------------------
0011
0012 To dump kernel data structures, the following Python script can be used
0013 in drgn:
0014
0015 .. code-block:: python
0016
0017 def align(x, a):
0018 """the alignment a should be a power of 2
0019 """
0020 mask = a - 1
0021 return (x+ mask) & ~mask
0022
0023 def struct_size(struct_type):
0024 struct_str = "struct {}".format(struct_type)
0025 return sizeof(Object(prog, struct_str, address=0x0))
0026
0027 def netdev_priv(netdevice):
0028 NETDEV_ALIGN = 32
0029 return netdevice.value_() + align(struct_size("net_device"), NETDEV_ALIGN)
0030
0031 name = 'xxx'
0032 qlge_device = None
0033 netdevices = prog['init_net'].dev_base_head.address_of_()
0034 for netdevice in list_for_each_entry("struct net_device", netdevices, "dev_list"):
0035 if netdevice.name.string_().decode('ascii') == name:
0036 print(netdevice.name)
0037
0038 ql_adapter = Object(prog, "struct ql_adapter", address=netdev_priv(qlge_device))
0039
0040 The struct ql_adapter will be printed in drgn as follows,
0041
0042 >>> ql_adapter
0043 (struct ql_adapter){
0044 .ricb = (struct ricb){
0045 .base_cq = (u8)0,
0046 .flags = (u8)120,
0047 .mask = (__le16)26637,
0048 .hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 },
0049 .ipv6_hash_key = (__le32 [10]){},
0050 .ipv4_hash_key = (__le32 [4]){},
0051 },
0052 .flags = (unsigned long)0,
0053 .wol = (u32)0,
0054 .nic_stats = (struct nic_stats){
0055 .tx_pkts = (u64)0,
0056 .tx_bytes = (u64)0,
0057 .tx_mcast_pkts = (u64)0,
0058 .tx_bcast_pkts = (u64)0,
0059 .tx_ucast_pkts = (u64)0,
0060 .tx_ctl_pkts = (u64)0,
0061 .tx_pause_pkts = (u64)0,
0062 ...
0063 },
0064 .active_vlans = (unsigned long [64]){
0065 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615,
0066 18446619461681283072, 0, 42949673024, 2147483647,
0067 },
0068 .rx_ring = (struct rx_ring [17]){
0069 {
0070 .cqicb = (struct cqicb){
0071 .msix_vect = (u8)0,
0072 .reserved1 = (u8)0,
0073 .reserved2 = (u8)0,
0074 .flags = (u8)0,
0075 .len = (__le16)0,
0076 .rid = (__le16)0,
0077 ...
0078 },
0079 .cq_base = (void *)0x0,
0080 .cq_base_dma = (dma_addr_t)0,
0081 }
0082 ...
0083 }
0084 }
0085
0086 coredump via devlink
0087 --------------------
0088
0089
0090 And the coredump obtained via devlink in json format looks like,
0091
0092 .. code:: shell
0093
0094 $ devlink health dump show DEVICE reporter coredump -p -j
0095 {
0096 "Core Registers": {
0097 "segment": 1,
0098 "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
0099 },
0100 "Test Logic Regs": {
0101 "segment": 2,
0102 "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
0103 },
0104 "RMII Registers": {
0105 "segment": 3,
0106 "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
0107 },
0108 ...
0109 "Sem Registers": {
0110 "segment": 50,
0111 "values": [ 0,0,0,0 ]
0112 }
0113 }
0114
0115 When the module parameter qlge_force_coredump is set to be true, the MPI
0116 RISC reset before coredumping. So coredumping will much longer since
0117 devlink tool has to wait for 5 secs for the resetting to be
0118 finished.