From 7fe1d0b459adb28ee591445d2d1ee9bda3c538ee Mon Sep 17 00:00:00 2001 From: Rahul Lakkireddy Date: Sat, 13 Jun 2020 03:37:26 +0530 Subject: [PATCH] net/cxgbe: fix SMT leak in filter error and free path Free up Source MAC Table (SMT) entry properly during filter create failure and filter delete. Fixes: 993541b2fa4f ("net/cxgbe: support flow API for source MAC rewrite") Cc: stable@dpdk.org Signed-off-by: Rahul Lakkireddy --- drivers/net/cxgbe/cxgbe_filter.c | 28 ++++++++++++++-------------- drivers/net/cxgbe/smt.c | 6 ++++++ drivers/net/cxgbe/smt.h | 1 + 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c index 317830f58b..6066da7db8 100644 --- a/drivers/net/cxgbe/cxgbe_filter.c +++ b/drivers/net/cxgbe/cxgbe_filter.c @@ -302,6 +302,9 @@ static void clear_filter(struct filter_entry *f) if (f->fs.mask.macidx) cxgbe_mpstcam_remove(pi, f->fs.val.macidx); + if (f->smt) + cxgbe_smt_release(f->smt); + /* The zeroing of the filter rule below clears the filter valid, * pending, locked flags etc. so it's all we need for * this operation. @@ -777,20 +780,6 @@ static int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx) unsigned int port_id = ethdev2pinfo(dev)->port_id; int ret; - /* If the new filter requires Source MAC rewriting then we need to - * allocate a SMT entry for the filter - */ - if (f->fs.newsmac) { - f->smt = cxgbe_smt_alloc_switching(f->dev, f->fs.smac); - if (!f->smt) { - if (f->l2t) { - cxgbe_l2t_release(f->l2t); - f->l2t = NULL; - } - return -ENOMEM; - } - } - ctrlq = &adapter->sge.ctrlq[port_id]; mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool); if (!mbuf) { @@ -1122,6 +1111,17 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id, } } + /* If the new filter requires Source MAC rewriting then we need to + * allocate a SMT entry for the filter + */ + if (f->fs.newsmac) { + f->smt = cxgbe_smt_alloc_switching(f->dev, f->fs.smac); + if (!f->smt) { + ret = -ENOMEM; + goto free_tid; + } + } + iconf = adapter->params.tp.ingress_config; /* Either PFVF or OVLAN can be active, but not both diff --git a/drivers/net/cxgbe/smt.c b/drivers/net/cxgbe/smt.c index e8f38676e2..b7b5a4a025 100644 --- a/drivers/net/cxgbe/smt.c +++ b/drivers/net/cxgbe/smt.c @@ -193,6 +193,12 @@ struct smt_entry *cxgbe_smt_alloc_switching(struct rte_eth_dev *dev, u8 *smac) return t4_smt_alloc_switching(dev, 0x0, smac); } +void cxgbe_smt_release(struct smt_entry *e) +{ + if (rte_atomic32_read(&e->refcnt)) + rte_atomic32_dec(&e->refcnt); +} + /** * Initialize Source MAC Table */ diff --git a/drivers/net/cxgbe/smt.h b/drivers/net/cxgbe/smt.h index be1fab8baf..92c63c8760 100644 --- a/drivers/net/cxgbe/smt.h +++ b/drivers/net/cxgbe/smt.h @@ -39,6 +39,7 @@ void t4_cleanup_smt(struct adapter *adap); void cxgbe_do_smt_write_rpl(struct adapter *adap, const struct cpl_smt_write_rpl *rpl); struct smt_entry *cxgbe_smt_alloc_switching(struct rte_eth_dev *dev, u8 *smac); +void cxgbe_smt_release(struct smt_entry *e); #endif /* __CXGBE_SMT_H_ */ -- 2.20.1