Commit abb14148 authored by Hiral Shah's avatar Hiral Shah Committed by Christoph Hellwig

fnic: fnic Control Path Trace Utility

Fnic Ctlr Path Trace utility is a tracing functionality built directly into fnic
driver to trace the control path frames like discovery, FLOGI request/reply,
PLOGI request/reply, link event etc.  It will be one trace file for all fnics.
It will help us to debug and resolve the discovery and initialization related
issues in more convenient way. This trace information includes time stamp,
Host Number, Frame type, Frame Length and Frame. By default,64 pages are
allocated but we can change the number of allocated pages by module parameter
fnic_fc_trace_max_page. Each entry is of 256 byte and available entries are
depends on allocated number of pages. We can turn on or off the fnic control
path trace functionality by module paramter fc_trace_enable and/or reset the
trace contain by module paramter fc_trace_clear.
Signed-off-by: default avatarHiral Shah <hishah@cisco.com>
Signed-off-by: default avatarSesidhar Baddela <sebaddel@cisco.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 66818663
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#define DRV_NAME "fnic" #define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
#define DRV_VERSION "1.5.0.45" #define DRV_VERSION "1.6.0.10"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: " #define DFX DRV_NAME "%d: "
......
This diff is collapsed.
...@@ -66,19 +66,35 @@ void fnic_handle_link(struct work_struct *work) ...@@ -66,19 +66,35 @@ void fnic_handle_link(struct work_struct *work)
fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev); fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev);
if (old_link_status == fnic->link_status) { if (old_link_status == fnic->link_status) {
if (!fnic->link_status) if (!fnic->link_status) {
/* DOWN -> DOWN */ /* DOWN -> DOWN */
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
else { fnic_fc_trace_set_data(fnic->lport->host->host_no,
FNIC_FC_LE, "Link Status: DOWN->DOWN",
strlen("Link Status: DOWN->DOWN"));
} else {
if (old_link_down_cnt != fnic->link_down_cnt) { if (old_link_down_cnt != fnic->link_down_cnt) {
/* UP -> DOWN -> UP */ /* UP -> DOWN -> UP */
fnic->lport->host_stats.link_failure_count++; fnic->lport->host_stats.link_failure_count++;
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
fnic_fc_trace_set_data(
fnic->lport->host->host_no,
FNIC_FC_LE,
"Link Status:UP_DOWN_UP",
strlen("Link_Status:UP_DOWN_UP")
);
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
"link down\n"); "link down\n");
fcoe_ctlr_link_down(&fnic->ctlr); fcoe_ctlr_link_down(&fnic->ctlr);
if (fnic->config.flags & VFCF_FIP_CAPABLE) { if (fnic->config.flags & VFCF_FIP_CAPABLE) {
/* start FCoE VLAN discovery */ /* start FCoE VLAN discovery */
fnic_fc_trace_set_data(
fnic->lport->host->host_no,
FNIC_FC_LE,
"Link Status: UP_DOWN_UP_VLAN",
strlen(
"Link Status: UP_DOWN_UP_VLAN")
);
fnic_fcoe_send_vlan_req(fnic); fnic_fcoe_send_vlan_req(fnic);
return; return;
} }
...@@ -88,22 +104,36 @@ void fnic_handle_link(struct work_struct *work) ...@@ -88,22 +104,36 @@ void fnic_handle_link(struct work_struct *work)
} else } else
/* UP -> UP */ /* UP -> UP */
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
fnic_fc_trace_set_data(
fnic->lport->host->host_no, FNIC_FC_LE,
"Link Status: UP_UP",
strlen("Link Status: UP_UP"));
} }
} else if (fnic->link_status) { } else if (fnic->link_status) {
/* DOWN -> UP */ /* DOWN -> UP */
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
if (fnic->config.flags & VFCF_FIP_CAPABLE) { if (fnic->config.flags & VFCF_FIP_CAPABLE) {
/* start FCoE VLAN discovery */ /* start FCoE VLAN discovery */
fnic_fc_trace_set_data(
fnic->lport->host->host_no,
FNIC_FC_LE, "Link Status: DOWN_UP_VLAN",
strlen("Link Status: DOWN_UP_VLAN"));
fnic_fcoe_send_vlan_req(fnic); fnic_fcoe_send_vlan_req(fnic);
return; return;
} }
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n"); FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_LE,
"Link Status: DOWN_UP", strlen("Link Status: DOWN_UP"));
fcoe_ctlr_link_up(&fnic->ctlr); fcoe_ctlr_link_up(&fnic->ctlr);
} else { } else {
/* UP -> DOWN */ /* UP -> DOWN */
fnic->lport->host_stats.link_failure_count++; fnic->lport->host_stats.link_failure_count++;
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n"); FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
fnic_fc_trace_set_data(
fnic->lport->host->host_no, FNIC_FC_LE,
"Link Status: UP_DOWN",
strlen("Link Status: UP_DOWN"));
fcoe_ctlr_link_down(&fnic->ctlr); fcoe_ctlr_link_down(&fnic->ctlr);
} }
...@@ -611,6 +641,10 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb) ...@@ -611,6 +641,10 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
"using UCSM\n"); "using UCSM\n");
goto drop; goto drop;
} }
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
FNIC_FC_RECV|0x80, (char *)skb->data, skb->len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
skb_queue_tail(&fnic->fip_frame_queue, skb); skb_queue_tail(&fnic->fip_frame_queue, skb);
queue_work(fnic_fip_queue, &fnic->fip_frame_work); queue_work(fnic_fip_queue, &fnic->fip_frame_work);
return 1; /* let caller know packet was used */ return 1; /* let caller know packet was used */
...@@ -839,6 +873,10 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc ...@@ -839,6 +873,10 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
} }
fr_dev(fp) = fnic->lport; fr_dev(fp) = fnic->lport;
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_RECV,
(char *)skb->data, skb->len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
skb_queue_tail(&fnic->frame_queue, skb); skb_queue_tail(&fnic->frame_queue, skb);
queue_work(fnic_event_queue, &fnic->frame_work); queue_work(fnic_event_queue, &fnic->frame_work);
...@@ -946,6 +984,15 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb) ...@@ -946,6 +984,15 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q); vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto; vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id); vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
FNIC_FC_SEND|0x80, (char *)eth_hdr, skb->len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
} else {
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
FNIC_FC_SEND|0x80, (char *)skb->data, skb->len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
} }
pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
...@@ -1018,6 +1065,11 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp) ...@@ -1018,6 +1065,11 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE); pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE);
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_SEND,
(char *)eth_hdr, tot_len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
spin_lock_irqsave(&fnic->wq_lock[0], flags); spin_lock_irqsave(&fnic->wq_lock[0], flags);
if (!vnic_wq_desc_avail(wq)) { if (!vnic_wq_desc_avail(wq)) {
......
...@@ -74,6 +74,11 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR); ...@@ -74,6 +74,11 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages " MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages "
"for fnic trace buffer"); "for fnic trace buffer");
unsigned int fnic_fc_trace_max_pages = 64;
module_param(fnic_fc_trace_max_pages, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(fnic_fc_trace_max_pages,
"Total allocated memory pages for fc trace buffer");
static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH; static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH;
module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR); module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN"); MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
...@@ -1034,11 +1039,20 @@ static int __init fnic_init_module(void) ...@@ -1034,11 +1039,20 @@ static int __init fnic_init_module(void)
/* Allocate memory for trace buffer */ /* Allocate memory for trace buffer */
err = fnic_trace_buf_init(); err = fnic_trace_buf_init();
if (err < 0) { if (err < 0) {
printk(KERN_ERR PFX "Trace buffer initialization Failed " printk(KERN_ERR PFX
"Fnic Tracing utility is disabled\n"); "Trace buffer initialization Failed. "
"Fnic Tracing utility is disabled\n");
fnic_trace_free(); fnic_trace_free();
} }
/* Allocate memory for fc trace buffer */
err = fnic_fc_trace_init();
if (err < 0) {
printk(KERN_ERR PFX "FC trace buffer initialization Failed "
"FC frame tracing utility is disabled\n");
fnic_fc_trace_free();
}
/* Create a cache for allocation of default size sgls */ /* Create a cache for allocation of default size sgls */
len = sizeof(struct fnic_dflt_sgl_list); len = sizeof(struct fnic_dflt_sgl_list);
fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create
...@@ -1119,6 +1133,7 @@ static int __init fnic_init_module(void) ...@@ -1119,6 +1133,7 @@ static int __init fnic_init_module(void)
kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
err_create_fnic_sgl_slab_dflt: err_create_fnic_sgl_slab_dflt:
fnic_trace_free(); fnic_trace_free();
fnic_fc_trace_free();
fnic_debugfs_terminate(); fnic_debugfs_terminate();
return err; return err;
} }
...@@ -1136,6 +1151,7 @@ static void __exit fnic_cleanup_module(void) ...@@ -1136,6 +1151,7 @@ static void __exit fnic_cleanup_module(void)
kmem_cache_destroy(fnic_io_req_cache); kmem_cache_destroy(fnic_io_req_cache);
fc_release_transport(fnic_fc_transport); fc_release_transport(fnic_fc_transport);
fnic_trace_free(); fnic_trace_free();
fnic_fc_trace_free();
fnic_debugfs_terminate(); fnic_debugfs_terminate();
} }
......
This diff is collapsed.
...@@ -19,6 +19,17 @@ ...@@ -19,6 +19,17 @@
#define __FNIC_TRACE_H__ #define __FNIC_TRACE_H__
#define FNIC_ENTRY_SIZE_BYTES 64 #define FNIC_ENTRY_SIZE_BYTES 64
#define FC_TRC_SIZE_BYTES 256
#define FC_TRC_HEADER_SIZE sizeof(struct fc_trace_hdr)
/*
* Fisrt bit of FNIC_FC_RECV and FNIC_FC_SEND is used to represent the type
* of frame 1 => Eth frame, 0=> FC frame
*/
#define FNIC_FC_RECV 0x52 /* Character R */
#define FNIC_FC_SEND 0x54 /* Character T */
#define FNIC_FC_LE 0x4C /* Character L */
extern ssize_t simple_read_from_buffer(void __user *to, extern ssize_t simple_read_from_buffer(void __user *to,
size_t count, size_t count,
...@@ -30,6 +41,10 @@ extern unsigned int fnic_trace_max_pages; ...@@ -30,6 +41,10 @@ extern unsigned int fnic_trace_max_pages;
extern int fnic_tracing_enabled; extern int fnic_tracing_enabled;
extern unsigned int trace_max_pages; extern unsigned int trace_max_pages;
extern unsigned int fnic_fc_trace_max_pages;
extern int fnic_fc_tracing_enabled;
extern int fnic_fc_trace_cleared;
typedef struct fnic_trace_dbg { typedef struct fnic_trace_dbg {
int wr_idx; int wr_idx;
int rd_idx; int rd_idx;
...@@ -56,6 +71,16 @@ struct fnic_trace_data { ...@@ -56,6 +71,16 @@ struct fnic_trace_data {
typedef struct fnic_trace_data fnic_trace_data_t; typedef struct fnic_trace_data fnic_trace_data_t;
struct fc_trace_hdr {
struct timespec time_stamp;
u32 host_no;
u8 frame_type;
u8 frame_len;
} __attribute__((__packed__));
#define FC_TRACE_ADDRESS(a) \
((unsigned long)(a) + sizeof(struct fc_trace_hdr))
#define FNIC_TRACE_ENTRY_SIZE \ #define FNIC_TRACE_ENTRY_SIZE \
(FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t)) (FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t))
...@@ -88,4 +113,17 @@ int fnic_debugfs_init(void); ...@@ -88,4 +113,17 @@ int fnic_debugfs_init(void);
void fnic_debugfs_terminate(void); void fnic_debugfs_terminate(void);
int fnic_trace_debugfs_init(void); int fnic_trace_debugfs_init(void);
void fnic_trace_debugfs_terminate(void); void fnic_trace_debugfs_terminate(void);
/* Fnic FC CTLR Trace releated function */
int fnic_fc_trace_init(void);
void fnic_fc_trace_free(void);
int fnic_fc_trace_set_data(u32 host_no, u8 frame_type,
char *frame, u32 fc_frame_len);
int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag);
void copy_and_format_trace_data(struct fc_trace_hdr *tdata,
fnic_dbgfs_t *fnic_dbgfs_prt,
int *len, u8 rdata_flag);
int fnic_fc_trace_debugfs_init(void);
void fnic_fc_trace_debugfs_terminate(void);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment