Skip to content

Commit 4ab3e49

Browse files
vvfedorenkolunn
authored andcommitted
bnxt_en: replace ptp_lock with irqsave variant
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: 7f5515d ("bnxt_en: Get the RX packet timestamp") Reviewed-by: Michael Chan <[email protected]> Signed-off-by: Vadim Fedorenko <[email protected]> Message-ID: <[email protected]> Signed-off-by: Andrew Lunn <[email protected]>
1 parent de96f6a commit 4ab3e49

File tree

3 files changed

+63
-41
lines changed

3 files changed

+63
-41
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,10 +2254,11 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
22542254

22552255
if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) {
22562256
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
2257+
unsigned long flags;
22572258

2258-
spin_lock_bh(&ptp->ptp_lock);
2259+
spin_lock_irqsave(&ptp->ptp_lock, flags);
22592260
ns = timecounter_cyc2time(&ptp->tc, ts);
2260-
spin_unlock_bh(&ptp->ptp_lock);
2261+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
22612262
memset(skb_hwtstamps(skb), 0,
22622263
sizeof(*skb_hwtstamps(skb)));
22632264
skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);
@@ -2757,17 +2758,18 @@ static int bnxt_async_event_process(struct bnxt *bp,
27572758
case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE:
27582759
if (BNXT_PTP_USE_RTC(bp)) {
27592760
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
2761+
unsigned long flags;
27602762
u64 ns;
27612763

27622764
if (!ptp)
27632765
goto async_event_process_exit;
27642766

2765-
spin_lock_bh(&ptp->ptp_lock);
2767+
spin_lock_irqsave(&ptp->ptp_lock, flags);
27662768
bnxt_ptp_update_current_time(bp);
27672769
ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) <<
27682770
BNXT_PHC_BITS) | ptp->current_time);
27692771
bnxt_ptp_rtc_timecounter_init(ptp, ns);
2770-
spin_unlock_bh(&ptp->ptp_lock);
2772+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
27712773
}
27722774
break;
27732775
}
@@ -13494,9 +13496,11 @@ static void bnxt_force_fw_reset(struct bnxt *bp)
1349413496
return;
1349513497

1349613498
if (ptp) {
13497-
spin_lock_bh(&ptp->ptp_lock);
13499+
unsigned long flags;
13500+
13501+
spin_lock_irqsave(&ptp->ptp_lock, flags);
1349813502
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
13499-
spin_unlock_bh(&ptp->ptp_lock);
13503+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
1350013504
} else {
1350113505
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
1350213506
}
@@ -13561,9 +13565,11 @@ void bnxt_fw_reset(struct bnxt *bp)
1356113565
int n = 0, tmo;
1356213566

1356313567
if (ptp) {
13564-
spin_lock_bh(&ptp->ptp_lock);
13568+
unsigned long flags;
13569+
13570+
spin_lock_irqsave(&ptp->ptp_lock, flags);
1356513571
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
13566-
spin_unlock_bh(&ptp->ptp_lock);
13572+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
1356713573
} else {
1356813574
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
1356913575
}

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
6262
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
6363
ptp_info);
6464
u64 ns = timespec64_to_ns(ts);
65+
unsigned long flags;
6566

6667
if (BNXT_PTP_USE_RTC(ptp->bp))
6768
return bnxt_ptp_cfg_settime(ptp->bp, ns);
6869

69-
spin_lock_bh(&ptp->ptp_lock);
70+
spin_lock_irqsave(&ptp->ptp_lock, flags);
7071
timecounter_init(&ptp->tc, &ptp->cc, ns);
71-
spin_unlock_bh(&ptp->ptp_lock);
72+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
7273
return 0;
7374
}
7475

@@ -100,13 +101,14 @@ static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts,
100101
static void bnxt_ptp_get_current_time(struct bnxt *bp)
101102
{
102103
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
104+
unsigned long flags;
103105

104106
if (!ptp)
105107
return;
106-
spin_lock_bh(&ptp->ptp_lock);
108+
spin_lock_irqsave(&ptp->ptp_lock, flags);
107109
WRITE_ONCE(ptp->old_time, ptp->current_time);
108110
bnxt_refclk_read(bp, NULL, &ptp->current_time);
109-
spin_unlock_bh(&ptp->ptp_lock);
111+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
110112
}
111113

112114
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,
149151
{
150152
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
151153
ptp_info);
154+
unsigned long flags;
152155
u64 ns, cycles;
153156
int rc;
154157

155-
spin_lock_bh(&ptp->ptp_lock);
158+
spin_lock_irqsave(&ptp->ptp_lock, flags);
156159
rc = bnxt_refclk_read(ptp->bp, sts, &cycles);
157160
if (rc) {
158-
spin_unlock_bh(&ptp->ptp_lock);
161+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
159162
return rc;
160163
}
161164
ns = timecounter_cyc2time(&ptp->tc, cycles);
162-
spin_unlock_bh(&ptp->ptp_lock);
165+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
163166
*ts = ns_to_timespec64(ns);
164167

165168
return 0;
@@ -177,6 +180,7 @@ void bnxt_ptp_update_current_time(struct bnxt *bp)
177180
static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta)
178181
{
179182
struct hwrm_port_mac_cfg_input *req;
183+
unsigned long flags;
180184
int rc;
181185

182186
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)
190194
if (rc) {
191195
netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc);
192196
} else {
193-
spin_lock_bh(&ptp->ptp_lock);
197+
spin_lock_irqsave(&ptp->ptp_lock, flags);
194198
bnxt_ptp_update_current_time(ptp->bp);
195-
spin_unlock_bh(&ptp->ptp_lock);
199+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
196200
}
197201

198202
return rc;
@@ -202,13 +206,14 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
202206
{
203207
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
204208
ptp_info);
209+
unsigned long flags;
205210

206211
if (BNXT_PTP_USE_RTC(ptp->bp))
207212
return bnxt_ptp_adjphc(ptp, delta);
208213

209-
spin_lock_bh(&ptp->ptp_lock);
214+
spin_lock_irqsave(&ptp->ptp_lock, flags);
210215
timecounter_adjtime(&ptp->tc, delta);
211-
spin_unlock_bh(&ptp->ptp_lock);
216+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
212217
return 0;
213218
}
214219

@@ -236,27 +241,29 @@ static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
236241
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
237242
ptp_info);
238243
struct bnxt *bp = ptp->bp;
244+
unsigned long flags;
239245

240246
if (!BNXT_MH(bp))
241247
return bnxt_ptp_adjfine_rtc(bp, scaled_ppm);
242248

243-
spin_lock_bh(&ptp->ptp_lock);
249+
spin_lock_irqsave(&ptp->ptp_lock, flags);
244250
timecounter_read(&ptp->tc);
245251
ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm);
246-
spin_unlock_bh(&ptp->ptp_lock);
252+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
247253
return 0;
248254
}
249255

250256
void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2)
251257
{
252258
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
253259
struct ptp_clock_event event;
260+
unsigned long flags;
254261
u64 ns, pps_ts;
255262

256263
pps_ts = EVENT_PPS_TS(data2, data1);
257-
spin_lock_bh(&ptp->ptp_lock);
264+
spin_lock_irqsave(&ptp->ptp_lock, flags);
258265
ns = timecounter_cyc2time(&ptp->tc, pps_ts);
259-
spin_unlock_bh(&ptp->ptp_lock);
266+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
260267

261268
switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) {
262269
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,
393400
{
394401
u64 cycles_now;
395402
u64 nsec_now, nsec_delta;
403+
unsigned long flags;
396404
int rc;
397405

398-
spin_lock_bh(&ptp->ptp_lock);
406+
spin_lock_irqsave(&ptp->ptp_lock, flags);
399407
rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now);
400408
if (rc) {
401-
spin_unlock_bh(&ptp->ptp_lock);
409+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
402410
return rc;
403411
}
404412
nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now);
405-
spin_unlock_bh(&ptp->ptp_lock);
413+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
406414

407415
nsec_delta = target_ns - nsec_now;
408416
*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)
689697
struct skb_shared_hwtstamps timestamp;
690698
struct bnxt_ptp_tx_req *txts_req;
691699
unsigned long now = jiffies;
700+
unsigned long flags;
692701
u64 ts = 0, ns = 0;
693702
u32 tmo = 0;
694703
int rc;
@@ -702,9 +711,9 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot)
702711
tmo, slot);
703712
if (!rc) {
704713
memset(&timestamp, 0, sizeof(timestamp));
705-
spin_lock_bh(&ptp->ptp_lock);
714+
spin_lock_irqsave(&ptp->ptp_lock, flags);
706715
ns = timecounter_cyc2time(&ptp->tc, ts);
707-
spin_unlock_bh(&ptp->ptp_lock);
716+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
708717
timestamp.hwtstamp = ns_to_ktime(ns);
709718
skb_tstamp_tx(txts_req->tx_skb, &timestamp);
710719
ptp->stats.ts_pkts++;
@@ -730,6 +739,7 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
730739
unsigned long now = jiffies;
731740
struct bnxt *bp = ptp->bp;
732741
u16 cons = ptp->txts_cons;
742+
unsigned long flags;
733743
u32 num_requests;
734744
int rc = 0;
735745

@@ -757,9 +767,9 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
757767
bnxt_ptp_get_current_time(bp);
758768
ptp->next_period = now + HZ;
759769
if (time_after_eq(now, ptp->next_overflow_check)) {
760-
spin_lock_bh(&ptp->ptp_lock);
770+
spin_lock_irqsave(&ptp->ptp_lock, flags);
761771
timecounter_read(&ptp->tc);
762-
spin_unlock_bh(&ptp->ptp_lock);
772+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
763773
ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD;
764774
}
765775
if (rc == -EAGAIN)
@@ -819,6 +829,7 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi,
819829
u32 opaque = tscmp->tx_ts_cmp_opaque;
820830
struct bnxt_tx_ring_info *txr;
821831
struct bnxt_sw_tx_bd *tx_buf;
832+
unsigned long flags;
822833
u64 ts, ns;
823834
u16 cons;
824835

@@ -833,9 +844,9 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi,
833844
le32_to_cpu(tscmp->tx_ts_cmp_flags_type),
834845
le32_to_cpu(tscmp->tx_ts_cmp_errors_v));
835846
} else {
836-
spin_lock_bh(&ptp->ptp_lock);
847+
spin_lock_irqsave(&ptp->ptp_lock, flags);
837848
ns = timecounter_cyc2time(&ptp->tc, ts);
838-
spin_unlock_bh(&ptp->ptp_lock);
849+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
839850
timestamp.hwtstamp = ns_to_ktime(ns);
840851
skb_tstamp_tx(tx_buf->skb, &timestamp);
841852
}
@@ -975,6 +986,7 @@ void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns)
975986
int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
976987
{
977988
struct timespec64 tsp;
989+
unsigned long flags;
978990
u64 ns;
979991
int rc;
980992

@@ -993,9 +1005,9 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
9931005
if (rc)
9941006
return rc;
9951007
}
996-
spin_lock_bh(&bp->ptp_cfg->ptp_lock);
1008+
spin_lock_irqsave(&bp->ptp_cfg->ptp_lock, flags);
9971009
bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns);
998-
spin_unlock_bh(&bp->ptp_cfg->ptp_lock);
1010+
spin_unlock_irqrestore(&bp->ptp_cfg->ptp_lock, flags);
9991011

10001012
return 0;
10011013
}
@@ -1063,10 +1075,12 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
10631075
atomic64_set(&ptp->stats.ts_err, 0);
10641076

10651077
if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) {
1066-
spin_lock_bh(&ptp->ptp_lock);
1078+
unsigned long flags;
1079+
1080+
spin_lock_irqsave(&ptp->ptp_lock, flags);
10671081
bnxt_refclk_read(bp, NULL, &ptp->current_time);
10681082
WRITE_ONCE(ptp->old_time, ptp->current_time);
1069-
spin_unlock_bh(&ptp->ptp_lock);
1083+
spin_unlock_irqrestore(&ptp->ptp_lock, flags);
10701084
ptp_schedule_worker(ptp->ptp_clock, 0);
10711085
}
10721086
ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO;

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,13 @@ struct bnxt_ptp_cfg {
146146
};
147147

148148
#if BITS_PER_LONG == 32
149-
#define BNXT_READ_TIME64(ptp, dst, src) \
150-
do { \
151-
spin_lock_bh(&(ptp)->ptp_lock); \
152-
(dst) = (src); \
153-
spin_unlock_bh(&(ptp)->ptp_lock); \
149+
#define BNXT_READ_TIME64(ptp, dst, src) \
150+
do { \
151+
unsigned long flags; \
152+
\
153+
spin_lock_irqsave(&(ptp)->ptp_lock, flags); \
154+
(dst) = (src); \
155+
spin_unlock_irqrestore(&(ptp)->ptp_lock, flags); \
154156
} while (0)
155157
#else
156158
#define BNXT_READ_TIME64(ptp, dst, src) \

0 commit comments

Comments
 (0)