Skip to content

Commit

Permalink
cxgb4: Add debugfs facility to inject FL starvation
Browse files Browse the repository at this point in the history
Add debugfs entry to inject Freelist starvation, used only for debugging
purpose.

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Hariprasad Shenai authored and David S. Miller committed May 27, 2015
1 parent c6bfda8 commit 5b377d1
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ struct sge {
struct sge_rspq **ingr_map; /* qid->queue ingress queue map */
unsigned long *starving_fl;
unsigned long *txq_maperr;
unsigned long *blocked_fl;
struct timer_list rx_timer; /* refills starving FLs */
struct timer_list tx_timer; /* checks Tx queues */
};
Expand Down
56 changes: 56 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1959,6 +1959,61 @@ static void add_debugfs_mem(struct adapter *adap, const char *name,
size_mb << 20);
}

static int blocked_fl_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}

static ssize_t blocked_fl_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
int len;
const struct adapter *adap = filp->private_data;
char *buf;
ssize_t size = (adap->sge.egr_sz + 3) / 4 +
adap->sge.egr_sz / 32 + 2; /* includes ,/\n/\0 */

buf = kzalloc(size, GFP_KERNEL);
if (!buf)
return -ENOMEM;

len = snprintf(buf, size - 1, "%*pb\n",
adap->sge.egr_sz, adap->sge.blocked_fl);
len += sprintf(buf + len, "\n");
size = simple_read_from_buffer(ubuf, count, ppos, buf, len);
t4_free_mem(buf);
return size;
}

static ssize_t blocked_fl_write(struct file *filp, const char __user *ubuf,
size_t count, loff_t *ppos)
{
int err;
unsigned long *t;
struct adapter *adap = filp->private_data;

t = kcalloc(BITS_TO_LONGS(adap->sge.egr_sz), sizeof(long), GFP_KERNEL);
if (!t)
return -ENOMEM;

err = bitmap_parse_user(ubuf, count, t, adap->sge.egr_sz);
if (err)
return err;

bitmap_copy(adap->sge.blocked_fl, t, adap->sge.egr_sz);
t4_free_mem(t);
return count;
}

static const struct file_operations blocked_fl_fops = {
.owner = THIS_MODULE,
.open = blocked_fl_open,
.read = blocked_fl_read,
.write = blocked_fl_write,
.llseek = generic_file_llseek,
};

/* Add an array of Debug FS files.
*/
void add_debugfs_files(struct adapter *adap,
Expand Down Expand Up @@ -2022,6 +2077,7 @@ int t4_setup_debugfs(struct adapter *adap)
#if IS_ENABLED(CONFIG_IPV6)
{ "clip_tbl", &clip_tbl_debugfs_fops, S_IRUSR, 0 },
#endif
{ "blocked_fl", &blocked_fl_fops, S_IRUSR | S_IWUSR, 0 },
};

/* Debug FS nodes common to all T5 and later adapters.
Expand Down
20 changes: 19 additions & 1 deletion drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3844,7 +3844,7 @@ static int adap_init0(struct adapter *adap)
}

/* Allocate the memory for the vaious egress queue bitmaps
* ie starving_fl and txq_maperr.
* ie starving_fl, txq_maperr and blocked_fl.
*/
adap->sge.starving_fl = kcalloc(BITS_TO_LONGS(adap->sge.egr_sz),
sizeof(long), GFP_KERNEL);
Expand All @@ -3860,6 +3860,15 @@ static int adap_init0(struct adapter *adap)
goto bye;
}

#ifdef CONFIG_DEBUG_FS
adap->sge.blocked_fl = kcalloc(BITS_TO_LONGS(adap->sge.egr_sz),
sizeof(long), GFP_KERNEL);
if (!adap->sge.blocked_fl) {
ret = -ENOMEM;
goto bye;
}
#endif

params[0] = FW_PARAM_PFVF(CLIP_START);
params[1] = FW_PARAM_PFVF(CLIP_END);
ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params, val);
Expand Down Expand Up @@ -4072,6 +4081,9 @@ static int adap_init0(struct adapter *adap)
kfree(adap->sge.ingr_map);
kfree(adap->sge.starving_fl);
kfree(adap->sge.txq_maperr);
#ifdef CONFIG_DEBUG_FS
kfree(adap->sge.blocked_fl);
#endif
if (ret != -ETIMEDOUT && ret != -EIO)
t4_fw_bye(adap, adap->mbox);
return ret;
Expand Down Expand Up @@ -4515,6 +4527,9 @@ static void free_some_resources(struct adapter *adapter)
kfree(adapter->sge.ingr_map);
kfree(adapter->sge.starving_fl);
kfree(adapter->sge.txq_maperr);
#ifdef CONFIG_DEBUG_FS
kfree(adapter->sge.blocked_fl);
#endif
disable_msi(adapter);

for_each_port(adapter, i)
Expand Down Expand Up @@ -4661,6 +4676,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

setup_memwin(adapter);
err = adap_init0(adapter);
#ifdef CONFIG_DEBUG_FS
bitmap_zero(adapter->sge.blocked_fl, adapter->sge.egr_sz);
#endif
setup_memwin_rdma(adapter);
if (err)
goto out_unmap_bar;
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/sge.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,11 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n,
struct rx_sw_desc *sd = &q->sdesc[q->pidx];
int node;

#ifdef CONFIG_DEBUG_FS
if (test_bit(q->cntxt_id - adap->sge.egr_start, adap->sge.blocked_fl))
goto out;
#endif

gfp |= __GFP_NOWARN;
node = dev_to_node(adap->pdev_dev);

Expand Down

0 comments on commit 5b377d1

Please sign in to comment.