cxgb4: collect hardware dump in second kernel
authorRahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Wed, 2 May 2018 09:47:19 +0000 (15:17 +0530)
committerDavid S. Miller <davem@davemloft.net>
Mon, 14 May 2018 17:46:05 +0000 (13:46 -0400)
Register callback to collect hardware/firmware dumps in second kernel
before hardware/firmware is initialized. The dumps for each device
will be available as elf notes in /proc/vmcore in second kernel.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c

index 688f95440af26c48d84d146ed98409e5e0856015..01e7aad4ce5bdc260ca3bcb5de33b988406b58ca 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/net_tstamp.h>
 #include <linux/ptp_clock_kernel.h>
 #include <linux/ptp_classify.h>
+#include <linux/crash_dump.h>
 #include <asm/io.h>
 #include "t4_chip_type.h"
 #include "cxgb4_uld.h"
@@ -964,6 +965,9 @@ struct adapter {
        struct hma_data hma;
 
        struct srq_data *srq;
+
+       /* Dump buffer for collecting logs in kdump kernel */
+       struct vmcoredd_data vmcoredd;
 };
 
 /* Support for "sched-class" command to allow a TX Scheduling Class to be
index 143686c60234ebfc23fe84762f40dbe4bdf98d18..085691eb2b9526b952b0fbd0baf607619a866ff3 100644 (file)
@@ -488,3 +488,28 @@ void cxgb4_init_ethtool_dump(struct adapter *adapter)
        adapter->eth_dump.version = adapter->params.fw_vers;
        adapter->eth_dump.len = 0;
 }
+
+static int cxgb4_cudbg_vmcoredd_collect(struct vmcoredd_data *data, void *buf)
+{
+       struct adapter *adap = container_of(data, struct adapter, vmcoredd);
+       u32 len = data->size;
+
+       return cxgb4_cudbg_collect(adap, buf, &len, CXGB4_ETH_DUMP_ALL);
+}
+
+int cxgb4_cudbg_vmcore_add_dump(struct adapter *adap)
+{
+       struct vmcoredd_data *data = &adap->vmcoredd;
+       u32 len;
+
+       len = sizeof(struct cudbg_hdr) +
+             sizeof(struct cudbg_entity_hdr) * CUDBG_MAX_ENTITY;
+       len += CUDBG_DUMP_BUFF_SIZE;
+
+       data->size = len;
+       snprintf(data->dump_name, sizeof(data->dump_name), "%s_%s",
+                cxgb4_driver_name, adap->name);
+       data->vmcoredd_callback = cxgb4_cudbg_vmcoredd_collect;
+
+       return vmcore_add_device_dump(data);
+}
index ce1ac9a1c8781c843e9e453bceb85f56efe3268a..ef59ba1ed96850d9b59b812bd00b07944e5e572f 100644 (file)
@@ -41,8 +41,11 @@ enum CXGB4_ETHTOOL_DUMP_FLAGS {
        CXGB4_ETH_DUMP_HW = (1 << 1), /* various FW and HW dumps */
 };
 
+#define CXGB4_ETH_DUMP_ALL (CXGB4_ETH_DUMP_MEM | CXGB4_ETH_DUMP_HW)
+
 u32 cxgb4_get_dump_length(struct adapter *adap, u32 flag);
 int cxgb4_cudbg_collect(struct adapter *adap, void *buf, u32 *buf_size,
                        u32 flag);
 void cxgb4_init_ethtool_dump(struct adapter *adapter);
+int cxgb4_cudbg_vmcore_add_dump(struct adapter *adap);
 #endif /* __CXGB4_CUDBG_H__ */
index c54fd189d83560d5d2104e4c2a805a77f8878711..07baa5e1a8c560fc1582c8b86300b754fcc41da5 100644 (file)
@@ -5558,6 +5558,16 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (err)
                goto out_free_adapter;
 
+       if (is_kdump_kernel()) {
+               /* Collect hardware state and append to /proc/vmcore */
+               err = cxgb4_cudbg_vmcore_add_dump(adapter);
+               if (err) {
+                       dev_warn(adapter->pdev_dev,
+                                "Fail collecting vmcore device dump, err: %d. Continuing\n",
+                                err);
+                       err = 0;
+               }
+       }
 
        if (!is_t4(adapter->params.chip)) {
                s_qpp = (QUEUESPERPAGEPF0_S +