Commit 4b063258 authored by Stefan Sørensen's avatar Stefan Sørensen Committed by David S. Miller

dp83640: Delay scheduled work.

Currently rx_timestamp_work reschedules itself as a regular workqueue item,
effectively causing it run constantly as long as there are packets left in
the queue. Fix by using delayed workqueue items, limiting it to run only
every two jiffies.
Signed-off-by: default avatarStefan Sørensen <stefan.sorensen@spectralink.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 539e44d2
...@@ -69,6 +69,8 @@ ...@@ -69,6 +69,8 @@
/* phyter seems to miss the mark by 16 ns */ /* phyter seems to miss the mark by 16 ns */
#define ADJTIME_FIX 16 #define ADJTIME_FIX 16
#define SKB_TIMESTAMP_TIMEOUT 2 /* jiffies */
#if defined(__BIG_ENDIAN) #if defined(__BIG_ENDIAN)
#define ENDIAN_FLAG 0 #define ENDIAN_FLAG 0
#elif defined(__LITTLE_ENDIAN) #elif defined(__LITTLE_ENDIAN)
...@@ -111,7 +113,7 @@ struct dp83640_private { ...@@ -111,7 +113,7 @@ struct dp83640_private {
struct list_head list; struct list_head list;
struct dp83640_clock *clock; struct dp83640_clock *clock;
struct phy_device *phydev; struct phy_device *phydev;
struct work_struct ts_work; struct delayed_work ts_work;
int hwts_tx_en; int hwts_tx_en;
int hwts_rx_en; int hwts_rx_en;
int layer; int layer;
...@@ -285,7 +287,7 @@ static void phy2rxts(struct phy_rxts *p, struct rxts *rxts) ...@@ -285,7 +287,7 @@ static void phy2rxts(struct phy_rxts *p, struct rxts *rxts)
rxts->seqid = p->seqid; rxts->seqid = p->seqid;
rxts->msgtype = (p->msgtype >> 12) & 0xf; rxts->msgtype = (p->msgtype >> 12) & 0xf;
rxts->hash = p->msgtype & 0x0fff; rxts->hash = p->msgtype & 0x0fff;
rxts->tmo = jiffies + 2; rxts->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT;
} }
static u64 phy2txts(struct phy_txts *p) static u64 phy2txts(struct phy_txts *p)
...@@ -1115,7 +1117,7 @@ static int dp83640_probe(struct phy_device *phydev) ...@@ -1115,7 +1117,7 @@ static int dp83640_probe(struct phy_device *phydev)
goto no_memory; goto no_memory;
dp83640->phydev = phydev; dp83640->phydev = phydev;
INIT_WORK(&dp83640->ts_work, rx_timestamp_work); INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work);
INIT_LIST_HEAD(&dp83640->rxts); INIT_LIST_HEAD(&dp83640->rxts);
INIT_LIST_HEAD(&dp83640->rxpool); INIT_LIST_HEAD(&dp83640->rxpool);
...@@ -1162,7 +1164,7 @@ static void dp83640_remove(struct phy_device *phydev) ...@@ -1162,7 +1164,7 @@ static void dp83640_remove(struct phy_device *phydev)
return; return;
enable_status_frames(phydev, false); enable_status_frames(phydev, false);
cancel_work_sync(&dp83640->ts_work); cancel_delayed_work_sync(&dp83640->ts_work);
skb_queue_purge(&dp83640->rx_queue); skb_queue_purge(&dp83640->rx_queue);
skb_queue_purge(&dp83640->tx_queue); skb_queue_purge(&dp83640->tx_queue);
...@@ -1356,7 +1358,7 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) ...@@ -1356,7 +1358,7 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr)
static void rx_timestamp_work(struct work_struct *work) static void rx_timestamp_work(struct work_struct *work)
{ {
struct dp83640_private *dp83640 = struct dp83640_private *dp83640 =
container_of(work, struct dp83640_private, ts_work); container_of(work, struct dp83640_private, ts_work.work);
struct sk_buff *skb; struct sk_buff *skb;
/* Deliver expired packets. */ /* Deliver expired packets. */
...@@ -1373,7 +1375,7 @@ static void rx_timestamp_work(struct work_struct *work) ...@@ -1373,7 +1375,7 @@ static void rx_timestamp_work(struct work_struct *work)
} }
if (!skb_queue_empty(&dp83640->rx_queue)) if (!skb_queue_empty(&dp83640->rx_queue))
schedule_work(&dp83640->ts_work); schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT);
} }
static bool dp83640_rxtstamp(struct phy_device *phydev, static bool dp83640_rxtstamp(struct phy_device *phydev,
...@@ -1412,9 +1414,11 @@ static bool dp83640_rxtstamp(struct phy_device *phydev, ...@@ -1412,9 +1414,11 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,
if (!shhwtstamps) { if (!shhwtstamps) {
skb_info->ptp_type = type; skb_info->ptp_type = type;
skb_info->tmo = jiffies + 2; skb_info->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT;
skb_queue_tail(&dp83640->rx_queue, skb); skb_queue_tail(&dp83640->rx_queue, skb);
schedule_work(&dp83640->ts_work); schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT);
} else {
netif_rx_ni(skb);
} }
return true; return true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment