Message ID | 20241015185310.608328-1-vadfed@meta.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net] bnxt_en: replace ptp_lock with irqsave variant | expand |
On Tue, Oct 15, 2024 at 11:53 AM Vadim Fedorenko <vadfed@meta.com> wrote: > > In netpoll configuration the completion processing can happen in hard > irq context which will break with spin_lock_bh() for fullfilling RX > timestamp in case of all packets timestamping. Replace it with > spin_lock_irqsave() variant. > > Fixes: 7f5515d19cd7 ("bnxt_en: Get the RX packet timestamp") > Signed-off-by: Vadim Fedorenko <vadfed@meta.com> Thanks. Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Hi Vadim, kernel test robot noticed the following build warnings: [auto build test WARNING on net/main] url: https://github.com/intel-lab-lkp/linux/commits/Vadim-Fedorenko/bnxt_en-replace-ptp_lock-with-irqsave-variant/20241016-025931 base: net/main patch link: https://lore.kernel.org/r/20241015185310.608328-1-vadfed%40meta.com patch subject: [PATCH net] bnxt_en: replace ptp_lock with irqsave variant config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20241016/202410161945.GNueTqcE-lkp@intel.com/config) compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241016/202410161945.GNueTqcE-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202410161945.GNueTqcE-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/net/ethernet/broadcom/bnxt/bnxt.c:2259:5: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 2259 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt.c:2767:5: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 2767 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt.c:13501:3: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 13501 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt.c:13570:4: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 13570 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ 4 warnings generated. -- >> drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:70:2: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 70 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:108:2: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 108 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:158:2: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 158 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:197:3: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 197 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:214:2: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 214 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:249:2: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 249 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:264:2: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 264 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:406:2: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 406 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:714:3: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 714 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:770:3: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 770 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:847:4: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 847 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/spinlock_rt.h:99:3: note: expanded from macro 'spin_lock_irqsave' 99 | typecheck(unsigned long, flags); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck' 12 | (void)(&__dummy == &__dummy2); \ | ~~~~~~~~ ^ ~~~~~~~~~ drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c:1008:2: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types] 1008 | spin_lock_irqsave(&bp->ptp_cfg->ptp_lock, flags); vim +2259 drivers/net/ethernet/broadcom/bnxt/bnxt.c 2010 2011 /* returns the following: 2012 * 1 - 1 packet successfully received 2013 * 0 - successful TPA_START, packet not completed yet 2014 * -EBUSY - completion ring does not have all the agg buffers yet 2015 * -ENOMEM - packet aborted due to out of memory 2016 * -EIO - packet aborted due to hw error indicated in BD 2017 */ 2018 static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, 2019 u32 *raw_cons, u8 *event) 2020 { 2021 struct bnxt_napi *bnapi = cpr->bnapi; 2022 struct bnxt_rx_ring_info *rxr = bnapi->rx_ring; 2023 struct net_device *dev = bp->dev; 2024 struct rx_cmp *rxcmp; 2025 struct rx_cmp_ext *rxcmp1; 2026 u32 tmp_raw_cons = *raw_cons; 2027 u16 cons, prod, cp_cons = RING_CMP(tmp_raw_cons); 2028 struct bnxt_sw_rx_bd *rx_buf; 2029 unsigned int len; 2030 u8 *data_ptr, agg_bufs, cmp_type; 2031 bool xdp_active = false; 2032 dma_addr_t dma_addr; 2033 struct sk_buff *skb; 2034 struct xdp_buff xdp; 2035 u32 flags, misc; 2036 u32 cmpl_ts; 2037 void *data; 2038 int rc = 0; 2039 2040 rxcmp = (struct rx_cmp *) 2041 &cpr->cp_desc_ring[CP_RING(cp_cons)][CP_IDX(cp_cons)]; 2042 2043 cmp_type = RX_CMP_TYPE(rxcmp); 2044 2045 if (cmp_type == CMP_TYPE_RX_TPA_AGG_CMP) { 2046 bnxt_tpa_agg(bp, rxr, (struct rx_agg_cmp *)rxcmp); 2047 goto next_rx_no_prod_no_len; 2048 } 2049 2050 tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons); 2051 cp_cons = RING_CMP(tmp_raw_cons); 2052 rxcmp1 = (struct rx_cmp_ext *) 2053 &cpr->cp_desc_ring[CP_RING(cp_cons)][CP_IDX(cp_cons)]; 2054 2055 if (!RX_CMP_VALID(rxcmp1, tmp_raw_cons)) 2056 return -EBUSY; 2057 2058 /* The valid test of the entry must be done first before 2059 * reading any further. 2060 */ 2061 dma_rmb(); 2062 prod = rxr->rx_prod; 2063 2064 if (cmp_type == CMP_TYPE_RX_L2_TPA_START_CMP || 2065 cmp_type == CMP_TYPE_RX_L2_TPA_START_V3_CMP) { 2066 bnxt_tpa_start(bp, rxr, cmp_type, 2067 (struct rx_tpa_start_cmp *)rxcmp, 2068 (struct rx_tpa_start_cmp_ext *)rxcmp1); 2069 2070 *event |= BNXT_RX_EVENT; 2071 goto next_rx_no_prod_no_len; 2072 2073 } else if (cmp_type == CMP_TYPE_RX_L2_TPA_END_CMP) { 2074 skb = bnxt_tpa_end(bp, cpr, &tmp_raw_cons, 2075 (struct rx_tpa_end_cmp *)rxcmp, 2076 (struct rx_tpa_end_cmp_ext *)rxcmp1, event); 2077 2078 if (IS_ERR(skb)) 2079 return -EBUSY; 2080 2081 rc = -ENOMEM; 2082 if (likely(skb)) { 2083 bnxt_deliver_skb(bp, bnapi, skb); 2084 rc = 1; 2085 } 2086 *event |= BNXT_RX_EVENT; 2087 goto next_rx_no_prod_no_len; 2088 } 2089 2090 cons = rxcmp->rx_cmp_opaque; 2091 if (unlikely(cons != rxr->rx_next_cons)) { 2092 int rc1 = bnxt_discard_rx(bp, cpr, &tmp_raw_cons, rxcmp); 2093 2094 /* 0xffff is forced error, don't print it */ 2095 if (rxr->rx_next_cons != 0xffff) 2096 netdev_warn(bp->dev, "RX cons %x != expected cons %x\n", 2097 cons, rxr->rx_next_cons); 2098 bnxt_sched_reset_rxr(bp, rxr); 2099 if (rc1) 2100 return rc1; 2101 goto next_rx_no_prod_no_len; 2102 } 2103 rx_buf = &rxr->rx_buf_ring[cons]; 2104 data = rx_buf->data; 2105 data_ptr = rx_buf->data_ptr; 2106 prefetch(data_ptr); 2107 2108 misc = le32_to_cpu(rxcmp->rx_cmp_misc_v1); 2109 agg_bufs = (misc & RX_CMP_AGG_BUFS) >> RX_CMP_AGG_BUFS_SHIFT; 2110 2111 if (agg_bufs) { 2112 if (!bnxt_agg_bufs_valid(bp, cpr, agg_bufs, &tmp_raw_cons)) 2113 return -EBUSY; 2114 2115 cp_cons = NEXT_CMP(cp_cons); 2116 *event |= BNXT_AGG_EVENT; 2117 } 2118 *event |= BNXT_RX_EVENT; 2119 2120 rx_buf->data = NULL; 2121 if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L2_ERRORS) { 2122 u32 rx_err = le32_to_cpu(rxcmp1->rx_cmp_cfa_code_errors_v2); 2123 2124 bnxt_reuse_rx_data(rxr, cons, data); 2125 if (agg_bufs) 2126 bnxt_reuse_rx_agg_bufs(cpr, cp_cons, 0, agg_bufs, 2127 false); 2128 2129 rc = -EIO; 2130 if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) { 2131 bnapi->cp_ring.sw_stats->rx.rx_buf_errors++; 2132 if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS) && 2133 !(bp->fw_cap & BNXT_FW_CAP_RING_MONITOR)) { 2134 netdev_warn_once(bp->dev, "RX buffer error %x\n", 2135 rx_err); 2136 bnxt_sched_reset_rxr(bp, rxr); 2137 } 2138 } 2139 goto next_rx_no_len; 2140 } 2141 2142 flags = le32_to_cpu(rxcmp->rx_cmp_len_flags_type); 2143 len = flags >> RX_CMP_LEN_SHIFT; 2144 dma_addr = rx_buf->mapping; 2145 2146 if (bnxt_xdp_attached(bp, rxr)) { 2147 bnxt_xdp_buff_init(bp, rxr, cons, data_ptr, len, &xdp); 2148 if (agg_bufs) { 2149 u32 frag_len = bnxt_rx_agg_pages_xdp(bp, cpr, &xdp, 2150 cp_cons, agg_bufs, 2151 false); 2152 if (!frag_len) 2153 goto oom_next_rx; 2154 } 2155 xdp_active = true; 2156 } 2157 2158 if (xdp_active) { 2159 if (bnxt_rx_xdp(bp, rxr, cons, &xdp, data, &data_ptr, &len, event)) { 2160 rc = 1; 2161 goto next_rx; 2162 } 2163 } 2164 2165 if (len <= bp->rx_copy_thresh) { 2166 if (!xdp_active) 2167 skb = bnxt_copy_skb(bnapi, data_ptr, len, dma_addr); 2168 else 2169 skb = bnxt_copy_xdp(bnapi, &xdp, len, dma_addr); 2170 bnxt_reuse_rx_data(rxr, cons, data); 2171 if (!skb) { 2172 if (agg_bufs) { 2173 if (!xdp_active) 2174 bnxt_reuse_rx_agg_bufs(cpr, cp_cons, 0, 2175 agg_bufs, false); 2176 else 2177 bnxt_xdp_buff_frags_free(rxr, &xdp); 2178 } 2179 goto oom_next_rx; 2180 } 2181 } else { 2182 u32 payload; 2183 2184 if (rx_buf->data_ptr == data_ptr) 2185 payload = misc & RX_CMP_PAYLOAD_OFFSET; 2186 else 2187 payload = 0; 2188 skb = bp->rx_skb_func(bp, rxr, cons, data, data_ptr, dma_addr, 2189 payload | len); 2190 if (!skb) 2191 goto oom_next_rx; 2192 } 2193 2194 if (agg_bufs) { 2195 if (!xdp_active) { 2196 skb = bnxt_rx_agg_pages_skb(bp, cpr, skb, cp_cons, agg_bufs, false); 2197 if (!skb) 2198 goto oom_next_rx; 2199 } else { 2200 skb = bnxt_xdp_build_skb(bp, skb, agg_bufs, rxr->page_pool, &xdp, rxcmp1); 2201 if (!skb) { 2202 /* we should be able to free the old skb here */ 2203 bnxt_xdp_buff_frags_free(rxr, &xdp); 2204 goto oom_next_rx; 2205 } 2206 } 2207 } 2208 2209 if (RX_CMP_HASH_VALID(rxcmp)) { 2210 enum pkt_hash_types type; 2211 2212 if (cmp_type == CMP_TYPE_RX_L2_V3_CMP) { 2213 type = bnxt_rss_ext_op(bp, rxcmp); 2214 } else { 2215 u32 hash_type = RX_CMP_HASH_TYPE(rxcmp); 2216 2217 /* RSS profiles 1 and 3 with extract code 0 for inner 2218 * 4-tuple 2219 */ 2220 if (hash_type != 1 && hash_type != 3) 2221 type = PKT_HASH_TYPE_L3; 2222 else 2223 type = PKT_HASH_TYPE_L4; 2224 } 2225 skb_set_hash(skb, le32_to_cpu(rxcmp->rx_cmp_rss_hash), type); 2226 } 2227 2228 if (cmp_type == CMP_TYPE_RX_L2_CMP) 2229 dev = bnxt_get_pkt_dev(bp, RX_CMP_CFA_CODE(rxcmp1)); 2230 skb->protocol = eth_type_trans(skb, dev); 2231 2232 if (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX) { 2233 skb = bnxt_rx_vlan(skb, cmp_type, rxcmp, rxcmp1); 2234 if (!skb) 2235 goto next_rx; 2236 } 2237 2238 skb_checksum_none_assert(skb); 2239 if (RX_CMP_L4_CS_OK(rxcmp1)) { 2240 if (dev->features & NETIF_F_RXCSUM) { 2241 skb->ip_summed = CHECKSUM_UNNECESSARY; 2242 skb->csum_level = RX_CMP_ENCAP(rxcmp1); 2243 } 2244 } else { 2245 if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) { 2246 if (dev->features & NETIF_F_RXCSUM) 2247 bnapi->cp_ring.sw_stats->rx.rx_l4_csum_errors++; 2248 } 2249 } 2250 2251 if (bnxt_rx_ts_valid(bp, flags, rxcmp1, &cmpl_ts)) { 2252 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { 2253 u64 ns, ts; 2254 2255 if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { 2256 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2257 unsigned int flags; 2258 > 2259 spin_lock_irqsave(&ptp->ptp_lock, flags); 2260 ns = timecounter_cyc2time(&ptp->tc, ts); 2261 spin_unlock_irqrestore(&ptp->ptp_lock, flags); 2262 memset(skb_hwtstamps(skb), 0, 2263 sizeof(*skb_hwtstamps(skb))); 2264 skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); 2265 } 2266 } 2267 } 2268 bnxt_deliver_skb(bp, bnapi, skb); 2269 rc = 1; 2270 2271 next_rx: 2272 cpr->rx_packets += 1; 2273 cpr->rx_bytes += len; 2274 2275 next_rx_no_len: 2276 rxr->rx_prod = NEXT_RX(prod); 2277 rxr->rx_next_cons = RING_RX(bp, NEXT_RX(cons)); 2278 2279 next_rx_no_prod_no_len: 2280 *raw_cons = tmp_raw_cons; 2281 2282 return rc; 2283 2284 oom_next_rx: 2285 cpr->sw_stats->rx.rx_oom_discards += 1; 2286 rc = -ENOMEM; 2287 goto next_rx; 2288 } 2289
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 6e422e24750a..8d2fe091e03f 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2254,10 +2254,11 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; + unsigned int flags; - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); ns = timecounter_cyc2time(&ptp->tc, ts); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); memset(skb_hwtstamps(skb), 0, sizeof(*skb_hwtstamps(skb))); skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); @@ -2757,17 +2758,18 @@ static int bnxt_async_event_process(struct bnxt *bp, case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE: if (BNXT_PTP_USE_RTC(bp)) { struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; + unsigned int flags; u64 ns; if (!ptp) goto async_event_process_exit; - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); bnxt_ptp_update_current_time(bp); ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) << BNXT_PHC_BITS) | ptp->current_time); bnxt_ptp_rtc_timecounter_init(ptp, ns); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); } break; } @@ -13494,9 +13496,11 @@ static void bnxt_force_fw_reset(struct bnxt *bp) return; if (ptp) { - spin_lock_bh(&ptp->ptp_lock); + unsigned int flags; + + spin_lock_irqsave(&ptp->ptp_lock, flags); set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); } else { set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); } @@ -13561,9 +13565,11 @@ void bnxt_fw_reset(struct bnxt *bp) int n = 0, tmo; if (ptp) { - spin_lock_bh(&ptp->ptp_lock); + unsigned int flags; + + spin_lock_irqsave(&ptp->ptp_lock, flags); set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); } else { set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c index 37d42423459c..04f23c776793 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c @@ -62,13 +62,14 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info, struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, ptp_info); u64 ns = timespec64_to_ns(ts); + unsigned int flags; if (BNXT_PTP_USE_RTC(ptp->bp)) return bnxt_ptp_cfg_settime(ptp->bp, ns); - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); timecounter_init(&ptp->tc, &ptp->cc, ns); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); return 0; } @@ -100,13 +101,14 @@ static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts, static void bnxt_ptp_get_current_time(struct bnxt *bp) { struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; + unsigned int flags; if (!ptp) return; - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); WRITE_ONCE(ptp->old_time, ptp->current_time); bnxt_refclk_read(bp, NULL, &ptp->current_time); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); } static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts, @@ -149,17 +151,18 @@ static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info, { struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, ptp_info); + unsigned int flags; u64 ns, cycles; int rc; - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); rc = bnxt_refclk_read(ptp->bp, sts, &cycles); if (rc) { - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); return rc; } ns = timecounter_cyc2time(&ptp->tc, cycles); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); *ts = ns_to_timespec64(ns); return 0; @@ -177,6 +180,7 @@ void bnxt_ptp_update_current_time(struct bnxt *bp) static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) { struct hwrm_port_mac_cfg_input *req; + unsigned int flags; int rc; rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG); @@ -190,9 +194,9 @@ static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) if (rc) { netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc); } else { - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); bnxt_ptp_update_current_time(ptp->bp); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); } return rc; @@ -202,13 +206,14 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) { struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, ptp_info); + unsigned int flags; if (BNXT_PTP_USE_RTC(ptp->bp)) return bnxt_ptp_adjphc(ptp, delta); - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); timecounter_adjtime(&ptp->tc, delta); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); return 0; } @@ -236,14 +241,15 @@ static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, ptp_info); struct bnxt *bp = ptp->bp; + unsigned int flags; if (!BNXT_MH(bp)) return bnxt_ptp_adjfine_rtc(bp, scaled_ppm); - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); timecounter_read(&ptp->tc); ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); return 0; } @@ -251,12 +257,13 @@ void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2) { struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; struct ptp_clock_event event; + unsigned int flags; u64 ns, pps_ts; pps_ts = EVENT_PPS_TS(data2, data1); - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); ns = timecounter_cyc2time(&ptp->tc, pps_ts); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) { case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL: @@ -393,16 +400,17 @@ static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns, { u64 cycles_now; u64 nsec_now, nsec_delta; + unsigned int flags; int rc; - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now); if (rc) { - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); return rc; } nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); nsec_delta = target_ns - nsec_now; *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult); @@ -689,6 +697,7 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) struct skb_shared_hwtstamps timestamp; struct bnxt_ptp_tx_req *txts_req; unsigned long now = jiffies; + unsigned int flags; u64 ts = 0, ns = 0; u32 tmo = 0; int rc; @@ -702,9 +711,9 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) tmo, slot); if (!rc) { memset(×tamp, 0, sizeof(timestamp)); - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); ns = timecounter_cyc2time(&ptp->tc, ts); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); timestamp.hwtstamp = ns_to_ktime(ns); skb_tstamp_tx(txts_req->tx_skb, ×tamp); ptp->stats.ts_pkts++; @@ -730,6 +739,7 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) unsigned long now = jiffies; struct bnxt *bp = ptp->bp; u16 cons = ptp->txts_cons; + unsigned int flags; u32 num_requests; int rc = 0; @@ -757,9 +767,9 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) bnxt_ptp_get_current_time(bp); ptp->next_period = now + HZ; if (time_after_eq(now, ptp->next_overflow_check)) { - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); timecounter_read(&ptp->tc); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; } if (rc == -EAGAIN) @@ -819,6 +829,7 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, u32 opaque = tscmp->tx_ts_cmp_opaque; struct bnxt_tx_ring_info *txr; struct bnxt_sw_tx_bd *tx_buf; + unsigned int flags; u64 ts, ns; u16 cons; @@ -833,9 +844,9 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, le32_to_cpu(tscmp->tx_ts_cmp_flags_type), le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); } else { - spin_lock_bh(&ptp->ptp_lock); + spin_lock_irqsave(&ptp->ptp_lock, flags); ns = timecounter_cyc2time(&ptp->tc, ts); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); timestamp.hwtstamp = ns_to_ktime(ns); skb_tstamp_tx(tx_buf->skb, ×tamp); } @@ -975,6 +986,7 @@ void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns) int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) { struct timespec64 tsp; + unsigned int flags; u64 ns; int rc; @@ -993,9 +1005,9 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) if (rc) return rc; } - spin_lock_bh(&bp->ptp_cfg->ptp_lock); + spin_lock_irqsave(&bp->ptp_cfg->ptp_lock, flags); bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns); - spin_unlock_bh(&bp->ptp_cfg->ptp_lock); + spin_unlock_irqrestore(&bp->ptp_cfg->ptp_lock, flags); return 0; } @@ -1063,10 +1075,12 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) atomic64_set(&ptp->stats.ts_err, 0); if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { - spin_lock_bh(&ptp->ptp_lock); + unsigned int flags; + + spin_lock_irqsave(&ptp->ptp_lock, flags); bnxt_refclk_read(bp, NULL, &ptp->current_time); WRITE_ONCE(ptp->old_time, ptp->current_time); - spin_unlock_bh(&ptp->ptp_lock); + spin_unlock_irqrestore(&ptp->ptp_lock, flags); ptp_schedule_worker(ptp->ptp_clock, 0); } ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h index a9a2f9a18c9c..1120c650edcf 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h @@ -146,11 +146,13 @@ struct bnxt_ptp_cfg { }; #if BITS_PER_LONG == 32 -#define BNXT_READ_TIME64(ptp, dst, src) \ -do { \ - spin_lock_bh(&(ptp)->ptp_lock); \ - (dst) = (src); \ - spin_unlock_bh(&(ptp)->ptp_lock); \ +#define BNXT_READ_TIME64(ptp, dst, src) \ +do { \ + unsigned int flags; \ + \ + spin_lock_irqsave(&(ptp)->ptp_lock, flags); \ + (dst) = (src); \ + spin_unlock_irqrestore(&(ptp)->ptp_lock, flags); \ } while (0) #else #define BNXT_READ_TIME64(ptp, dst, src) \
In netpoll configuration the completion processing can happen in hard irq context which will break with spin_lock_bh() for fullfilling RX timestamp in case of all packets timestamping. Replace it with spin_lock_irqsave() variant. Fixes: 7f5515d19cd7 ("bnxt_en: Get the RX packet timestamp") Signed-off-by: Vadim Fedorenko <vadfed@meta.com> --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 22 +++--- drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 70 +++++++++++-------- drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h | 12 ++-- 3 files changed, 63 insertions(+), 41 deletions(-)