mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
nvethernet: use IRQ-safe variant of raw spinlock
Issue: Deadlock observed because ptp_lock shared between process context and Interrupt context. Below is the scenario where deadlock observed - 1) ether_adjust_freq acquired the lock 2) At the same ether_get_ptptime() called from IRQ context 3) ether_adjust_freq() got preempted and ether_get_ptptime() trying to aquire the lock again which leads to dead lock. Fix: Disable the interrupts before aquiring the lock by using IRQ-safe variant of raw spinlock. Bug 200591192 Bug 200535378 Change-Id: I6f884883bf9cf93877ddb5d0fb7b2927573a1858 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2323211 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Revanth Kumar Uppala
parent
4862fe2d5b
commit
d1c349ccd0
@@ -74,9 +74,10 @@ static int ether_adjust_time(struct ptp_clock_info *ptp, s64 nsec_delta)
|
||||
struct ether_priv_data,
|
||||
ptp_clock_ops);
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
unsigned long flags;
|
||||
int ret = -1;
|
||||
|
||||
raw_spin_lock(&pdata->ptp_lock);
|
||||
raw_spin_lock_irqsave(&pdata->ptp_lock, flags);
|
||||
|
||||
ret = osi_adjust_time(osi_core, nsec_delta);
|
||||
if (ret < 0) {
|
||||
@@ -85,7 +86,7 @@ static int ether_adjust_time(struct ptp_clock_info *ptp, s64 nsec_delta)
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
raw_spin_unlock(&pdata->ptp_lock);
|
||||
raw_spin_unlock_irqrestore(&pdata->ptp_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -108,9 +109,10 @@ static int ether_adjust_freq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
struct ether_priv_data,
|
||||
ptp_clock_ops);
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
unsigned long flags;
|
||||
int ret = -1;
|
||||
|
||||
raw_spin_lock(&pdata->ptp_lock);
|
||||
raw_spin_lock_irqsave(&pdata->ptp_lock, flags);
|
||||
|
||||
ret = osi_adjust_freq(osi_core, ppb);
|
||||
if (ret < 0) {
|
||||
@@ -119,7 +121,7 @@ static int ether_adjust_freq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
raw_spin_unlock(&pdata->ptp_lock);
|
||||
raw_spin_unlock_irqrestore(&pdata->ptp_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -143,12 +145,13 @@ static int ether_get_time(struct ptp_clock_info *ptp, struct timespec *ts)
|
||||
ptp_clock_ops);
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
unsigned int sec, nsec;
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock(&pdata->ptp_lock);
|
||||
raw_spin_lock_irqsave(&pdata->ptp_lock, flags);
|
||||
|
||||
osi_get_systime_from_mac(osi_core, &sec, &nsec);
|
||||
|
||||
raw_spin_unlock(&pdata->ptp_lock);
|
||||
raw_spin_unlock_irqrestore(&pdata->ptp_lock, flags);
|
||||
|
||||
ts->tv_sec = sec;
|
||||
ts->tv_nsec = nsec;
|
||||
@@ -175,9 +178,10 @@ static int ether_set_time(struct ptp_clock_info *ptp,
|
||||
struct ether_priv_data,
|
||||
ptp_clock_ops);
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
unsigned long flags;
|
||||
int ret = -1;
|
||||
|
||||
raw_spin_lock(&pdata->ptp_lock);
|
||||
raw_spin_lock_irqsave(&pdata->ptp_lock, flags);
|
||||
|
||||
ret = osi_set_systime_to_mac(osi_core, ts->tv_sec, ts->tv_nsec);
|
||||
if (ret < 0) {
|
||||
@@ -186,7 +190,7 @@ static int ether_set_time(struct ptp_clock_info *ptp,
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
raw_spin_unlock(&pdata->ptp_lock);
|
||||
raw_spin_unlock_irqrestore(&pdata->ptp_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user