openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

commit dae93dff2ad0ca65929aeb163eb18a188e8a312f
parent 5552570e76602e3a4fae763aefb9e8b1c47fa6b5
Author: Broadcom SDK Release <sdk.releases@broadcom.com>
Date:   Tue,  2 Apr 2019 16:28:41 -0700

SDK-174695: In the previous release, ALPM sw states could be out of sync when...

Devices: 56980_A0,56980_B0
Module: ALPM

Symptom:
Inappropriate handling on alpm_bkt_add_to_npvt->alpm_bkt_insert
returning -6 causes alpm SW state corruption.

In the previous release, ALPM sw states could be out of sync when LPM
TCAM reaches full in Parallel mode, and causes mis-forwarding or bucket
split segmentation fault. In current release, this issue has been fixed.

Diffstat:
Msdk-6.5.16/include/bcm_int/esw/alpm.h | 57+++++++++++++++++++++++++++++++++++++--------------------
Msdk-6.5.16/src/bcm/esw/alpm2/alpm.c | 217++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msdk-6.5.16/src/bcm/esw/alpm2/alpm_ts.c | 8++------
Msdk-6.5.16/src/bcm/esw/alpm2/alpm_wb.c | 5+++--
4 files changed, 158 insertions(+), 129 deletions(-)

diff --git a/sdk-6.5.16/include/bcm_int/esw/alpm.h b/sdk-6.5.16/include/bcm_int/esw/alpm.h @@ -988,15 +988,46 @@ do { \ #define VRF_ROUTE_CNT(acb, vrf_id, ipt) \ (ACB_PVT_CTRL(acb, vrf_id, ipt).route_cnt) +/* ALPM logs */ +/* Macro for invoking "fast" checker */ +#define ALPM_LOG(chk_, stuff_) do { \ + if (bsl_fast_check(chk_)) { \ + bsl_printf stuff_; \ + } \ + } while (0) + +/* Any layer log macros */ +#define ALPM_FATAL(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_FATAL, stuff_) +#define ALPM_ERR(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_ERROR, stuff_) +#define ALPM_WARN(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_WARN, stuff_) +#define ALPM_INFO(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_INFO, stuff_) +#define ALPM_VERB(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_VERBOSE, stuff_) +#define ALPM_DBG(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_DEBUG, stuff_) +#define ALPM_LOG_CHECK(stuff_) LOG_CHECK(BSL_LS_BCM_ALPM|(stuff_)) /* ALPM ERROR condition check */ +#define ALPM_IER_PRT_EXCEPT(op, except_err) \ + do { int __rv__; if ((__rv__ = (op)) < 0) { \ + if (__rv__ != (except_err) && __rv__ != BCM_E_BUSY) \ + {ALPM_ERR(("ALPMerr: %s : %d rv %d\n", FUNCTION_NAME(), __LINE__, __rv__));} return(__rv__); } } while(0) + /* If error return */ -#define ALPM_IER BCM_IF_ERROR_RETURN +#define ALPM_IER(op) \ + do { int __rv__; if ((__rv__ = (op)) < 0) { \ + if (__rv__ != BCM_E_BUSY) \ + {ALPM_ERR(("ALPMerr: %s : %d rv %d\n", FUNCTION_NAME(), __LINE__, __rv__));} return(__rv__); } } while(0) + +#define ALPM_IEG_PRT_EXCEPT(op, except_err) \ + do { if ((rv = (op)) < 0) { \ + if (rv != (except_err) && rv != BCM_E_BUSY) \ + {ALPM_ERR(("ALPMerr: %s : %d rv %d\n", FUNCTION_NAME(), __LINE__, rv));} goto bad; } } while(0) /* If error goto */ -#define ALPM_IEG(op) \ - do { if ((rv = (op)) < 0) { goto bad; } } while(0) +#define ALPM_IEG(op) \ + do { if ((rv = (op)) < 0) { \ + if (rv != BCM_E_BUSY) \ + {ALPM_ERR(("ALPMerr: %s : %d rv %d\n", FUNCTION_NAME(), __LINE__, rv));} goto bad; } } while(0) #define ALPM_REALLOC_EG(_ptr, _size, _str) \ do { \ @@ -1005,6 +1036,7 @@ do { \ } \ if (_ptr == NULL) { \ rv = BCM_E_MEMORY; \ + ALPM_ERR(("ALPMerr: out of memory at %s : %d\n", FUNCTION_NAME(), __LINE__)); \ goto bad; \ } \ sal_memset(_ptr, 0, _size); \ @@ -1015,6 +1047,7 @@ do { \ _ptr = alpm_util_alloc(_size, _str);\ if (_ptr == NULL) { \ rv = BCM_E_MEMORY; \ + ALPM_ERR(("ALPMerr: out of memory at %s : %d\n", FUNCTION_NAME(), __LINE__)); \ goto bad; \ } \ sal_memset(_ptr, 0, _size); \ @@ -1025,28 +1058,12 @@ do { \ _ptr = soc_cm_salloc(_u, _size, _str); \ if (_ptr == NULL) { \ rv = BCM_E_MEMORY; \ + ALPM_ERR(("ALPMerr: out of memory at %s : %d\n", FUNCTION_NAME(), __LINE__)); \ goto bad; \ } \ sal_memset(_ptr, 0, _size); \ } while (0) -/* ALPM logs */ -/* Macro for invoking "fast" checker */ -#define ALPM_LOG(chk_, stuff_) do { \ - if (bsl_fast_check(chk_)) { \ - bsl_printf stuff_; \ - } \ - } while (0) - -/* Any layer log macros */ -#define ALPM_FATAL(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_FATAL, stuff_) -#define ALPM_ERR(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_ERROR, stuff_) -#define ALPM_WARN(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_WARN, stuff_) -#define ALPM_INFO(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_INFO, stuff_) -#define ALPM_VERB(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_VERBOSE, stuff_) -#define ALPM_DBG(stuff_) ALPM_LOG(BSL_LS_BCM_ALPM|BSL_DEBUG, stuff_) -#define ALPM_LOG_CHECK(stuff_) LOG_CHECK(BSL_LS_BCM_ALPM|(stuff_)) - /* ALPM externs */ extern int alpm_trie_ent_to_pfx(int u, int pkm, void *e, int, int, uint32 *key); diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm.c @@ -744,9 +744,9 @@ alpm_pvt_delete(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg) if (ACB_HAS_TCAM(acb)) { rv = bcm_esw_alpm_tcam_delete(u, lpm_cfg); if (BCM_FAILURE(rv)) { - ALPM_ERR(("**ACB(%d).PVT.DEL tcam_delete 0x%x/%d failed %d\n", + ALPM_ERR(("**ACB(%d).PVT.DEL tcam_delete 0x%x/%d vrf %d failed %d\n", ACB_IDX(acb), lpm_cfg->defip_ip_addr, - lpm_cfg->defip_sub_len, rv)); + lpm_cfg->defip_sub_len, lpm_cfg->defip_vrf, rv)); } } else { rv = alpm_cb_delete(u, ACB_UPR(u, acb), lpm_cfg); @@ -1475,10 +1475,10 @@ alpm_bkt_bnk_shrink(int u, int ipt, _alpm_cb_t *acb, _alpm_bkt_pool_conf_t *bp_c ALPM_INFO(("**ACB(%d).BNK.RLS: RBBE (%d %d %d *)\n", ACB_IDX(acb), -1, BI_BKT_IDX(bkt_info), bnk)); - (void)alpm_bkt_bnk_free(u, ipt, acb, bp_conf, bkt_info, bnk); if (fmt_update != NULL) { *fmt_update = 1; } + ALPM_IER(alpm_bkt_bnk_free(u, ipt, acb, bp_conf, bkt_info, bnk)); } } @@ -1607,9 +1607,8 @@ alpm_bkt_pfx_ent_idx_update(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node, if (bnk == sb && bkt == BI_BKT_IDX(src_bkt)) { bkt_node->ent_idx = ALPM_IDX_MAKE(acb, dst_bkt, db, ent); if (ALPM_TCAM_HB_IS_PTR(u) && bak_idx != bkt_node->ent_idx) { - (void)alpm_ppg_hitbit(u, PVT_BKT_VRF(pvt_node), - PVT_BKT_IPT(pvt_node), - bkt_node->key, bkt_node->key_len); + ALPM_IEG(alpm_ppg_hitbit(u, PVT_BKT_VRF(pvt_node), + PVT_BKT_IPT(pvt_node), bkt_node->key, bkt_node->key_len)); } } } @@ -1736,13 +1735,13 @@ alpm_bkt_bnk_ripple(int u, _alpm_cb_t *acb, /* 2. Update bkt_info info */ bnk_fmt = bkt_info->bnk_fmt[mb]; vet_bmp = bkt_info->vet_bmp[mb]; - (void)alpm_bkt_bnk_chk_rsvd(u, ipt, ACB_BKT_VRF_POOL(acb, - PVT_BKT_VRF(pvt_node)), to_bnk); + ALPM_IER(alpm_bkt_bnk_chk_rsvd(u, ipt, ACB_BKT_VRF_POOL(acb, + PVT_BKT_VRF(pvt_node)), to_bnk)); /* bkt_info could be changed here includes: * rofs, bkt-idx, bnk_fmt, so we need to save those values. */ - (void)alpm_bkt_bnk_free(u, ipt, acb, - ACB_BKT_VRF_POOL(acb, PVT_BKT_VRF(pvt_node)), bkt_info, mb); + ALPM_IER(alpm_bkt_bnk_free(u, ipt, acb, + ACB_BKT_VRF_POOL(acb, PVT_BKT_VRF(pvt_node)), bkt_info, mb)); PVT_ROFS(pvt_node) = BI_ROFS(&dst_bkt); PVT_BKT_IDX(pvt_node) = BI_BKT_IDX(&dst_bkt); @@ -1839,8 +1838,8 @@ alpm_bkt_move(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node, } /* Release bnk to global pool */ - (void)alpm_bkt_bnk_shrink(u, PVT_BKT_IPT(pvt_node), acb, - ACB_BKT_VRF_POOL(acb, PVT_BKT_VRF(pvt_node)), dst_bkt, NULL); + ALPM_IER(alpm_bkt_bnk_shrink(u, PVT_BKT_IPT(pvt_node), acb, + ACB_BKT_VRF_POOL(acb, PVT_BKT_VRF(pvt_node)), dst_bkt, NULL)); return rv; } @@ -1973,7 +1972,7 @@ alpm_bkt_free(int u, _alpm_cb_t *acb, int vrf_id, int ipt, bp_conf = ACB_BKT_VRF_POOL(acb, vrf_id); for (bnk = 0; bnk < ALPM_BPB_MAX; bnk++) { if (BI_BNK_IS_USED(bkt_info, bnk)) { - (void)alpm_bkt_bnk_free(u, ipt, acb, bp_conf, bkt_info, bnk); + ALPM_IER(alpm_bkt_bnk_free(u, ipt, acb, bp_conf, bkt_info, bnk)); } } bkt_info->reverse = 0; @@ -2126,8 +2125,8 @@ alpm_bkt_pfx_copy(int u, _alpm_cb_t *acb, npvt_node); if (ALPM_TCAM_HB_IS_PTR(u)) { for (i = 0; i < pfx_arr->pfx_cnt; i++) { - (void)alpm_ppg_hitbit(u, PVT_BKT_VRF(opvt_node), PVT_BKT_IPT(opvt_node), - pfx_arr->pfx[i]->key, pfx_arr->pfx[i]->key_len); + ALPM_IER(alpm_ppg_hitbit(u, PVT_BKT_VRF(opvt_node), PVT_BKT_IPT(opvt_node), + pfx_arr->pfx[i]->key, pfx_arr->pfx[i]->key_len)); } } return rv; @@ -2199,8 +2198,10 @@ alpm_bkt_pfx_shrink(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node, void *us rv = alpm_bkt_bnk_shrink(u, PVT_BKT_IPT(pvt_node), acb, ACB_BKT_VRF_POOL(acb, PVT_BKT_VRF(pvt_node)), bkt_info, &fmt_update); + ALPM_IEG(rv); if (fmt_update && !ACB_BKT_FIXED_FMT(acb, PVT_BKT_VRF(pvt_node))) { - (void) alpm_pvt_update_by_pvt_node(u, acb, pvt_node, ALPM_PVT_UPDATE_ALPM_DATA); + rv = alpm_pvt_update_by_pvt_node(u, acb, pvt_node, ALPM_PVT_UPDATE_ALPM_DATA); + ALPM_IEG(rv); } } @@ -2209,8 +2210,9 @@ alpm_bkt_pfx_shrink(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node, void *us if (bak_idx[i] == pfx_arr->pfx[i]->ent_idx) { continue; } - (void)alpm_ppg_hitbit(u, PVT_BKT_VRF(pvt_node), PVT_BKT_IPT(pvt_node), - pfx_arr->pfx[i]->key, pfx_arr->pfx[i]->key_len); + rv = alpm_ppg_hitbit(u, PVT_BKT_VRF(pvt_node), PVT_BKT_IPT(pvt_node), + pfx_arr->pfx[i]->key, pfx_arr->pfx[i]->key_len); + ALPM_IEG(rv); } } @@ -2419,7 +2421,11 @@ bad: if (cbt != NULL) { if (cbt->trie != NULL) { - (void)alpm_lib_trie_merge(pbt, cbt->trie, pvt_key, pvt_len); + int rv2; + rv2 = alpm_lib_trie_merge(pbt, cbt->trie, pvt_key, pvt_len); + if (BCM_FAILURE(rv2)) { + ALPM_ERR(("alpm_lib_trie_merge error in trie split, rv %d\n", rv2)); + } } alpm_lib_trie_destroy(cbt); @@ -2487,6 +2493,7 @@ alpm_bkt_add_to_npvt(int u, _alpm_cb_t *acb, int ipt = ALPM_LPM_IPT(u, lpm_cfg); uint32 *prefix, length; uint32 ent_idx; + int bkt_trie_added = 0; alpm_lib_trie_t *bkt_trie = NULL; alpm_lib_trie_node_t *tmp_node = NULL; @@ -2524,7 +2531,7 @@ alpm_bkt_add_to_npvt(int u, _alpm_cb_t *acb, rv = BCM_E_FULL; } - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); lpm_cfg->defip_index = ent_idx; @@ -2541,12 +2548,9 @@ alpm_bkt_add_to_npvt(int u, _alpm_cb_t *acb, bkt_trie = PVT_BKT_TRIE(pvt_node); rv = alpm_lib_trie_insert(bkt_trie, prefix, length, (alpm_lib_trie_node_t *)bkt_node); ALPM_IEG(rv); + bkt_trie_added = 1; - rv = alpm_vrf_pfx_trie_add(u, acb, lpm_cfg, bkt_node); - if (BCM_FAILURE(rv)) { - (void)alpm_lib_trie_delete(bkt_trie, prefix, length, &tmp_node); - goto bad; - } + ALPM_IEG(alpm_vrf_pfx_trie_add(u, acb, lpm_cfg, bkt_node)); if (BCM_SUCCESS(rv) && ALPMC(u)->_alpm_dbg_bmp & _ALPM_DBG_PVT_SANITY_NODE) { @@ -2558,6 +2562,9 @@ alpm_bkt_add_to_npvt(int u, _alpm_cb_t *acb, return rv; bad: + if (bkt_trie_added) { + (void)alpm_lib_trie_delete(bkt_trie, prefix, length, &tmp_node); + } if (bkt_node != NULL) { alpm_util_free(bkt_node); } @@ -2662,12 +2669,9 @@ alpm_vrf_pfx_trie_add(int u, _alpm_cb_t *acb, /* Non default route start from here */ prefix = lpm_cfg->user_data; length = lpm_cfg->defip_sub_len; - pfx_node = alpm_util_alloc(sizeof(_alpm_pfx_node_t), "VRF_trie_node"); - if (pfx_node == NULL) { - return BCM_E_MEMORY; - } - sal_memset(pfx_node, 0, sizeof(_alpm_bkt_node_t)); + ALPM_ALLOC_EG(pfx_node, sizeof(_alpm_pfx_node_t), "VRF_trie_node"); + sal_memcpy(pfx_node->key, prefix, sizeof(pfx_node->key)); pfx_node->key_len = length; pfx_node->ent_idx = lpm_cfg->defip_index; @@ -2680,6 +2684,7 @@ alpm_vrf_pfx_trie_add(int u, _alpm_cb_t *acb, } } +bad: return rv; } @@ -2776,26 +2781,23 @@ alpm_vrf_pfx_trie_init(int u, int vrf_id, int ipt) max_key_len = alpm_util_trie_max_key_len(u, ipt); - pfx_node = alpm_util_alloc(sizeof(*pfx_node), "Payload for pfx trie key"); - if (pfx_node != NULL) { - sal_memset(pfx_node, 0, sizeof(*pfx_node)); - rv = alpm_lib_trie_init(max_key_len, &ALPM_VRF_TRIE(u, vrf_id, ipt)); - if (BCM_SUCCESS(rv)) { - root = ALPM_VRF_TRIE(u, vrf_id, ipt); - rv = alpm_lib_trie_insert(root, key, 0, &(pfx_node->node)); - } + ALPM_ALLOC_EG(pfx_node, sizeof(*pfx_node), "Payload for pfx trie key"); + sal_memset(pfx_node, 0, sizeof(*pfx_node)); + rv = alpm_lib_trie_init(max_key_len, &ALPM_VRF_TRIE(u, vrf_id, ipt)); + if (BCM_SUCCESS(rv)) { + root = ALPM_VRF_TRIE(u, vrf_id, ipt); + rv = alpm_lib_trie_insert(root, key, 0, &(pfx_node->node)); + } - if (BCM_FAILURE(rv)) { - alpm_util_free(pfx_node); - if (root != NULL) { - alpm_lib_trie_destroy(root); - ALPM_VRF_TRIE(u, vrf_id, ipt) = NULL; - } + if (BCM_FAILURE(rv)) { + alpm_util_free(pfx_node); + if (root != NULL) { + alpm_lib_trie_destroy(root); + ALPM_VRF_TRIE(u, vrf_id, ipt) = NULL; } - } else { - rv = BCM_E_MEMORY; } +bad: return rv; } @@ -2814,7 +2816,7 @@ alpm_vrf_pfx_trie_deinit(int u, int vrf_id, int ipt) rv = alpm_lib_trie_delete(root, key, 0, (alpm_lib_trie_node_t **)&pfx_node); if (BCM_SUCCESS(rv)) { alpm_util_free(pfx_node); - (void) alpm_lib_trie_destroy(root); + ALPM_IER(alpm_lib_trie_destroy(root)); ALPM_VRF_TRIE(u, vrf_id, ipt) = NULL; } @@ -2885,7 +2887,7 @@ alpm_vrf_pvt_node_delete(int u, _alpm_cb_t *acb, int vrf_id, int ipt, rv = alpm_lib_trie_delete(pvt_root, lpm_cfg->user_data, lpm_cfg->defip_sub_len, (alpm_lib_trie_node_t **)&pvt_node); if (BCM_SUCCESS(rv)) { - (void) alpm_lib_trie_destroy(PVT_BKT_TRIE(pvt_node)); + ALPM_IER(alpm_lib_trie_destroy(PVT_BKT_TRIE(pvt_node))); alpm_util_free(pvt_node); } @@ -2900,7 +2902,7 @@ alpm_vrf_pvt_trie_deinit(int u, _alpm_cb_t *acb, int vrf_id, int ipt, rv = alpm_vrf_pvt_node_delete(u, acb, vrf_id, ipt, lpm_cfg); if (BCM_SUCCESS(rv)) { - (void) alpm_lib_trie_destroy(ACB_PVT_TRIE(acb, vrf_id, ipt)); + ALPM_IER(alpm_lib_trie_destroy(ACB_PVT_TRIE(acb, vrf_id, ipt))); ACB_PVT_TRIE(acb, vrf_id, ipt) = NULL; } @@ -2949,9 +2951,9 @@ retry: sal_memset(&bkt_info, 0, sizeof(_alpm_bkt_info_t)); rv = alpm_bkt_alloc(u, acb, vrf_id, ipt, 1, &bkt_info, NULL); if (rv == BCM_E_BUSY) { - ALPM_IEG(alpm_bkt_alloc(u, acb, vrf_id, ipt, 1, &bkt_info, NULL)); + ALPM_IEG_PRT_EXCEPT(alpm_bkt_alloc(u, acb, vrf_id, ipt, 1, &bkt_info, NULL), BCM_E_FULL); } - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); lpm_cfg->bkt_info = &bkt_info; sal_memcpy(&PVT_BKT_INFO(pvt_node), &bkt_info, sizeof(_alpm_bkt_info_t)); @@ -2961,12 +2963,12 @@ retry: * it's only 3 levels so it also works. */ if (rv == BCM_E_BUSY && lpm_cfg->spl_pn && ACB_HAS_RTE(acb, vrf_id)) { - (void)alpm_bkt_free(u, acb, vrf_id, ipt, &bkt_info); + ALPM_IEG(alpm_bkt_free(u, acb, vrf_id, ipt, &bkt_info)); sal_memset(&bkt_info, 0, sizeof(_alpm_bkt_info_t)); rv = alpm_bkt_alloc(u, acb, vrf_id, ipt, ACB_BNK_PER_BKT(acb, vrf_id), &bkt_info, NULL); - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); /* Case 2.2.2, split given l3 pvt_node first */ rv = alpm_cb_split(u, acb, lpm_cfg, &bkt_info, 0xffff); @@ -2977,7 +2979,7 @@ retry: goto retry; } } - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); PVT_IDX(pvt_node) = lpm_cfg->defip_index; lpm_cfg->pvt_node = (uint32 *)pvt_node; @@ -3043,7 +3045,7 @@ alpm_vrf_init(int u, _alpm_cb_t *acb, int vrf_id, int ipt, uint8 db_type) pvt_cfg.defip_vrf = ALPM_VRF_ID_TO_VRF(u, vrf_id); pvt_cfg.defip_flags |= ALPM_IS_IPV6(ipt) ? BCM_L3_IP6 : 0; - ALPM_IEG(alpm_cb_pvt_add(u, acb, vrf_id, ipt, &pvt_cfg)); + ALPM_IEG_PRT_EXCEPT(alpm_cb_pvt_add(u, acb, vrf_id, ipt, &pvt_cfg), BCM_E_FULL); ACB_VRF_INIT_SET(u, acb, vrf_id, ipt); @@ -3098,9 +3100,9 @@ alpm_vrf_deinit(int u, int vrf_id, int ipt) /* add Entry into tcam as default routes for the VRF */ if (ACB_HAS_TCAM(acb)) { lpm_cfg.pvt_node = pvt_node; - (void)alpm_bkt_bnk_shrink(u, ipt, acb, - ACB_BKT_VRF_POOL(acb, vrf_id), - &PVT_BKT_INFO(pvt_node), NULL); + ALPM_IER(alpm_bkt_bnk_shrink(u, ipt, acb, + ACB_BKT_VRF_POOL(acb, vrf_id), + &PVT_BKT_INFO(pvt_node), NULL)); } else { lpm_cfg.pvt_node = NULL; } @@ -3412,7 +3414,7 @@ alpm_cb_defrag(int u, _alpm_cb_t *acb, int vrf_id, int ipt) bnk_bmp, BPC_BNK_CNT(bp_conf), bnkpb, &rngl, &rngr, &rngm); - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); if (ALPMC(u)->_alpm_dbg_bmp & _ALPM_DBG_PVT_DEFRAG) { cli_out("free range get: bpb %d, range left %d, right %d, mid %d\n", @@ -3510,13 +3512,14 @@ alpm_cb_split(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg, ALPM_IEG(rv); if (max_spl_cnt < 0xffff && !ACB_BKT_FIXED_FMT(acb, 1)) { - (void)alpm_bkt_free(u, acb, vrf_id, ipt, nbkt_info); + rv = alpm_bkt_free(u, acb, vrf_id, ipt, nbkt_info); + ALPM_IEG(rv); sal_memset(nbkt_info, 0, sizeof(_alpm_bkt_info_t)); nbkt_info->reverse = 1; rv = alpm_bkt_alloc(u, acb, vrf_id, ipt, ACB_BNK_PER_BKT(acb, vrf_id), nbkt_info, NULL); /* Should not see error here */ - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); } /* 3. HW: Copy split prefixes from old bucket to new bucket */ @@ -3552,8 +3555,9 @@ alpm_cb_split(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg, ALPM_IEG(rv); /* Free unused banks of new pivot to Global bank pool */ - (void)alpm_bkt_bnk_shrink(u, ipt, acb, ACB_BKT_VRF_POOL(acb, vrf_id), - &PVT_BKT_INFO(npvt_node), NULL); + rv = alpm_bkt_bnk_shrink(u, ipt, acb, ACB_BKT_VRF_POOL(acb, vrf_id), + &PVT_BKT_INFO(npvt_node), NULL); + ALPM_IEG(rv); /* 4. HW: insert new pivot * recursion happens here: BCM_E_FULL is expected @@ -3590,7 +3594,8 @@ alpm_cb_split(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg, sal_memcpy(lpm_cfg->spl_key, pvt_lpm_cfg.spl_key, sizeof(lpm_cfg->spl_key)); lpm_cfg->spl_key_len = pvt_lpm_cfg.spl_key_len; } - ALPM_IEG(rv); + + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); /* Case of add new L1 pvt during L2 bkt split: - If new L2 bkt belongs to new L1 pvt, add new L2 bkt first. @@ -3606,7 +3611,7 @@ alpm_cb_split(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg, ALPM_IEG(rv1); } /* check returned rv after _tcam_entry_write done */ - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); } /* @@ -3616,12 +3621,14 @@ alpm_cb_split(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg, */ /* 5. HW: Invalidate split prefixes in the old bucket */ - (void)alpm_bkt_pfx_clean(u, acb, opvt_node, pfx_arr->pfx_cnt, bak_idx); + rv = alpm_bkt_pfx_clean(u, acb, opvt_node, pfx_arr->pfx_cnt, bak_idx); + ALPM_IEG(rv); /* 6. SW: Shrink old bucket, * A important step to make sure banks are continuously occupied by pivot */ - (void)alpm_bkt_pfx_shrink(u, acb, opvt_node, &shrink_empty_only); + rv = alpm_bkt_pfx_shrink(u, acb, opvt_node, &shrink_empty_only); + ALPM_IEG(rv); /* 7. SW: release temporary resources */ alpm_util_free(bak_idx); @@ -3779,11 +3786,14 @@ alpm_cb_merge_pvt(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *src_pvt, /* 5. Invalid old entries * Not expecting failures on invalidation */ - (void)alpm_bkt_pfx_clean(u, acb, src_pvt, pfx_arr->pfx_cnt, bak_idx); - (void)alpm_bkt_bnk_shrink(u, ipt, acb, ACB_BKT_VRF_POOL(acb, vrf_id), - &PVT_BKT_INFO(src_pvt), NULL); - (void)alpm_bkt_bnk_shrink(u, ipt, acb, ACB_BKT_VRF_POOL(acb, vrf_id), - &PVT_BKT_INFO(dst_pvt), NULL); + rv = alpm_bkt_pfx_clean(u, acb, src_pvt, pfx_arr->pfx_cnt, bak_idx); + ALPM_IEG(rv); + rv = alpm_bkt_bnk_shrink(u, ipt, acb, ACB_BKT_VRF_POOL(acb, vrf_id), + &PVT_BKT_INFO(src_pvt), NULL); + ALPM_IEG(rv); + rv = alpm_bkt_bnk_shrink(u, ipt, acb, ACB_BKT_VRF_POOL(acb, vrf_id), + &PVT_BKT_INFO(dst_pvt), NULL); + ALPM_IEG(rv); /* 6. Delete child pvt entry from pvt table */ rv = alpm_pvt_delete_by_pvt_node(u, acb, chd_pvt); @@ -4029,18 +4039,21 @@ alpm_cb_delete(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg) if (ACB_BKT_WRA(acb, PVT_BKT_VRF(pvt_node))) { if (bkt_empty) { - (void)alpm_bkt_bnk_shrink(u, ipt, acb, + rv = alpm_bkt_bnk_shrink(u, ipt, acb, ACB_BKT_VRF_POOL(acb, PVT_BKT_VRF(pvt_node)), &PVT_BKT_INFO(pvt_node), NULL); + ALPM_IEG(rv); } else { - (void)alpm_bkt_pfx_shrink(u, acb, pvt_node, &shrink_empty_only); + rv = alpm_bkt_pfx_shrink(u, acb, pvt_node, &shrink_empty_only); + ALPM_IEG(rv); } } else { if (bkt_empty || bkt_trie->trie != NULL || VRF_ROUTE_CNT(acb, vrf_id, ipt) == 0) { - (void)alpm_bkt_bnk_shrink(u, ipt, acb, + rv = alpm_bkt_bnk_shrink(u, ipt, acb, ACB_BKT_VRF_POOL(acb, PVT_BKT_VRF(pvt_node)), &PVT_BKT_INFO(pvt_node), NULL); + ALPM_IEG(rv); } } @@ -4132,21 +4145,21 @@ alpm_cb_path_construct(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg) rv = alpm_bkt_alloc(u, top_cb, vrf_id, ipt, ACB_BNK_PER_BKT(top_cb, vrf_id), &bkt_info, NULL); - ALPM_IER(rv); + ALPM_IER_PRT_EXCEPT(rv, BCM_E_FULL); rv = alpm_cb_split(u, top_cb, lpm_cfg, &bkt_info, 0xffff); if (rv == BCM_E_BUSY && ACB_HAS_RTE(acb, vrf_id) && lpm_cfg->spl_pn) { sal_memset(&bkt_info, 0, sizeof(_alpm_bkt_info_t)); rv = alpm_bkt_alloc(u, acb, vrf_id, ipt, ACB_BNK_PER_BKT(acb, vrf_id), &bkt_info, NULL); - ALPM_IER(rv); + ALPM_IER_PRT_EXCEPT(rv, BCM_E_FULL); /* Case 2.2.2, split given l3 pvt_node first */ rv = alpm_cb_split(u, acb, lpm_cfg, &bkt_info, 0xffff); - ALPM_IER(rv); + ALPM_IER_PRT_EXCEPT(rv, BCM_E_FULL); lpm_cfg->spl_pn = NULL; lpm_cfg->spl_key_len = 0; } else if (BCM_FAILURE(rv)) { - ALPM_IER(rv); + ALPM_IER_PRT_EXCEPT(rv, BCM_E_FULL); } else { lpm_cfg->pvt_node = NULL; } @@ -4191,7 +4204,7 @@ alpm_cb_path_construct(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg) } rv = alpm_cb_pvt_add(u, acb, vrf_id, ipt, &l2_lpm_cfg); if (BCM_FAILURE(rv)) { - ALPM_IER(rv); + ALPM_IER_PRT_EXCEPT(rv, BCM_E_FULL); } else { lpm_cfg->pvt_node = l2_lpm_cfg.pvt_node; } @@ -4211,6 +4224,7 @@ alpm_cb_insert(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg) uint32 *prefix, length; uint32 ent_idx; int retry_count = 0, retry_max = 3; + int bkt_trie_added = 0; alpm_lib_trie_t *bkt_trie = NULL; alpm_lib_trie_node_t *tmp_node = NULL; @@ -4223,7 +4237,7 @@ alpm_cb_insert(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg) /* Init ALPM structure for first insert */ if (!ACB_VRF_INITED(u, acb, vrf_id, ipt)) { uint8 db_type = alpm_util_route_type_get(u, lpm_cfg); - ALPM_IEG(alpm_vrf_init(u, acb, vrf_id, ipt, db_type)); + ALPM_IEG_PRT_EXCEPT(alpm_vrf_init(u, acb, vrf_id, ipt, db_type), BCM_E_FULL); } if (ACB_BKT_FIXED_FMT(acb, vrf_id)) { @@ -4238,13 +4252,14 @@ retry: if (ACB_HAS_TCAM(acb)) { lpm_cfg->l1_pvt_node = pvt_node; } else { - (void)alpm_pvt_find(u, ACB_UPR(u, acb), lpm_cfg, &upr_pvt_node); + rv = alpm_pvt_find(u, ACB_UPR(u, acb), lpm_cfg, &upr_pvt_node); + ALPM_IEG(rv); if (pvt_node && upr_pvt_node) { if (upr_pvt_node->key_len <= pvt_node->key_len) { lpm_cfg->pvt_node = pvt_node; } else { lpm_cfg->l1_pvt_node = upr_pvt_node; - ALPM_IER(alpm_cb_path_construct(u, acb, lpm_cfg)); + ALPM_IER_PRT_EXCEPT(alpm_cb_path_construct(u, acb, lpm_cfg), BCM_E_FULL); pvt_node = lpm_cfg->pvt_node; if (pvt_node == NULL) { goto retry; @@ -4260,7 +4275,7 @@ retry: /* return FULL when Expand exceeds bnk_threshold */ if (rv == BCM_E_RESOURCE) { rv = BCM_E_FULL; - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); } retry_spl: @@ -4316,7 +4331,7 @@ retry_spl: goto retry; } } - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); } else { avl_bnk_cnt = ACB_BNK_PER_BKT(acb, vrf_id); } @@ -4328,7 +4343,7 @@ retry_spl: rv = alpm_bkt_alloc(u, acb, vrf_id, ipt, ACB_BNK_PER_BKT(acb, vrf_id), &bkt_info, &avl_bnk_cnt); - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); } rv = alpm_cb_split(u, acb, lpm_cfg, &bkt_info, max_spl_cnt); @@ -4341,7 +4356,7 @@ retry_spl: rv = alpm_bkt_alloc(u, acb, vrf_id, ipt, ACB_BNK_PER_BKT(acb, vrf_id), &bkt_info, &avl_bnk_cnt); - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); /* Case 2.2.2, split given l3 pvt_node first */ rv = alpm_cb_split(u, acb, lpm_cfg, &bkt_info, max_spl_cnt); @@ -4354,7 +4369,7 @@ retry_spl: } } - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); ptcam_write = lpm_cfg->tcam_write; if (ptcam_write != NULL) { @@ -4373,7 +4388,7 @@ retry_spl: goto retry; } - ALPM_IEG(rv); + ALPM_IEG_PRT_EXCEPT(rv, BCM_E_FULL); lpm_cfg->defip_index = ent_idx; @@ -4390,12 +4405,10 @@ retry_spl: bkt_trie = PVT_BKT_TRIE(pvt_node); rv = alpm_lib_trie_insert(bkt_trie, prefix, length, (alpm_lib_trie_node_t *)bkt_node); ALPM_IEG(rv); + bkt_trie_added = 1; rv = alpm_vrf_pfx_trie_add(u, acb, lpm_cfg, bkt_node); - if (BCM_FAILURE(rv)) { - (void)alpm_lib_trie_delete(bkt_trie, prefix, length, &tmp_node); - goto bad; - } + ALPM_IEG(rv); /* do insert propagation to update existing default datas */ if (ACB_HAS_RTE(acb, vrf_id)) { @@ -4413,6 +4426,9 @@ retry_spl: return rv; bad: + if (bkt_trie_added) { + (void)alpm_lib_trie_delete(bkt_trie, prefix, length, &tmp_node); + } if (bkt_node != NULL) { alpm_util_free(bkt_node); } @@ -4758,7 +4774,7 @@ bcm_esw_alpm_insert(int u, _bcm_defip_cfg_t *lpm_cfg) /* Insert prefix into trie */ /* Split trie : Insertion into trie results into Split */ /* Allocate a TCAM entry for PIVOT and bucket and move entries */ - ALPM_IER(alpm_cb_path_construct(u, acb, lpm_cfg)); + ALPM_IER_PRT_EXCEPT(alpm_cb_path_construct(u, acb, lpm_cfg), BCM_E_FULL); rv = alpm_cb_insert(u, acb, lpm_cfg); if (BCM_SUCCESS(rv)) { @@ -5369,7 +5385,7 @@ static void alpm_cb_bkt_bnk_dump(int u, int ipt, _alpm_cb_t *acb, _alpm_bkt_pool_conf_t *bp_conf, char *prefix) { - int j, k, bnk, vrf_id, ipt1; + int rv = BCM_E_NONE, j, k, bnk, vrf_id, ipt1; int vrf_min, vrf_max; int bnk_cnt, total_bnk_cnt; int ent_cnt, total_ent_cnt, max_ent_cnt; @@ -5382,12 +5398,7 @@ alpm_cb_bkt_bnk_dump(int u, int ipt, _alpm_cb_t *acb, bkt_cnt = ACB_BKT_CNT(acb); - cdata = alpm_util_alloc(sizeof(*cdata), "bktusage"); - if (cdata == NULL) { - ALPM_ERR(("Memory out of resource\n")); - return; - } - sal_memset(cdata, 0, sizeof(*cdata)); + ALPM_ALLOC_EG(cdata, sizeof(*cdata), "bktusage"); if (ACB_BKT_VRF_POOL(acb, ALPM_VRF_ID_GLO(u)) == ACB_BKT_VRF_POOL(acb, 1)) { @@ -5458,6 +5469,10 @@ alpm_cb_bkt_bnk_dump(int u, int ipt, _alpm_cb_t *acb, } alpm_util_free(cdata); + +bad: + return; + } /* diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm_ts.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm_ts.c @@ -1693,11 +1693,7 @@ bcm_esw_alpm_sanity_check(int u, soc_mem_t mem, int index, int check_sw) psanity = &sanity[pid]; alloc_sz = BPC_BNK_CNT(bp_conf) * sizeof(int); - psanity->bktptr[i] = alpm_util_alloc(alloc_sz, "bktptr"); - if (psanity->bktptr[i] == NULL) { - rv = BCM_E_MEMORY; - goto bad; - } + ALPM_ALLOC_EG(psanity->bktptr[i], alloc_sz, "bktptr"); /* initialized to -1 to distinguish index 0 */ sal_memset(psanity->bktptr[i], 0xff, alloc_sz); psanity->error = 0; @@ -2285,7 +2281,7 @@ bcm_esw_alpm_find(int u, _bcm_defip_cfg_t *lpm_cfg, int *nh_ecmp_idx) /* Perform hw lookup */ alpm_util_cfg_to_key(u, ipt, lpm_cfg, sw_key); /* get sw_key[4] */ - ALPM_IER(alpm_find_best_match(u, vrf_id, pkm, sw_key, sw_len, lpm_cfg)); + ALPM_IER_PRT_EXCEPT(alpm_find_best_match(u, vrf_id, pkm, sw_key, sw_len, lpm_cfg), BCM_E_NOT_FOUND); *nh_ecmp_idx = lpm_cfg->defip_ecmp_index; return (BCM_E_NONE); diff --git a/sdk-6.5.16/src/bcm/esw/alpm2/alpm_wb.c b/sdk-6.5.16/src/bcm/esw/alpm2/alpm_wb.c @@ -146,8 +146,7 @@ alpm_wb_vrf_init(int u, _alpm_cb_t *acb, int vrf_id, int ipt) if (ACB_HAS_RTE(acb, vrf_id)) { rv = alpm_lib_trie_init(max_key_len, &ALPM_VRF_TRIE(u, vrf_id, ipt)); if (BCM_SUCCESS(rv)) { - pfx_node = alpm_util_alloc(sizeof(*pfx_node), "Payload for pfx trie key"); - sal_memset(pfx_node, 0, sizeof(*pfx_node)); + ALPM_ALLOC_EG(pfx_node, sizeof(*pfx_node), "Payload for pfx trie key"); root = ALPM_VRF_TRIE(u, vrf_id, ipt); rv = alpm_lib_trie_insert(root, key, 0, &(pfx_node->node)); } @@ -159,6 +158,8 @@ alpm_wb_vrf_init(int u, _alpm_cb_t *acb, int vrf_id, int ipt) } } } + +bad: return rv; }