summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mm/fault.c1
-rw-r--r--drivers/net/ethernet/freescale/fec.h2
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c35
-rw-r--r--kernel/softirq.c11
4 files changed, 39 insertions, 10 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index eb8830a4c5ed..f3961a71d1f4 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -553,6 +553,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
inf->name, fsr, addr);
+ WARN_ON(1);
info.si_signo = inf->sig;
info.si_errno = 0;
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 99a5f695a11e..c4a245071d77 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -352,6 +352,8 @@ struct fec_enet_private {
struct delayed_work time_keep;
struct regulator *reg_phy;
unsigned long quirks;
+ u64 stop_ns;
+ u64 start_ns;
};
void fec_ptp_init(struct platform_device *pdev);
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 578f0bdac309..299b1f494065 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -254,6 +254,10 @@ static unsigned copybreak = 200;
module_param(copybreak, uint, 0644);
MODULE_PARM_DESC(copybreak,
"Maximum size of packet that is copied to a new buffer on receive");
+static unsigned long total_stopped;
+module_param(total_stopped, ulong, 0644);
+static unsigned long start_latency;
+module_param(start_latency, ulong, 0644);
static bool fec_enet_rx_zerocopy(struct fec_enet_private *fep, unsigned pktlen)
{
@@ -457,6 +461,15 @@ static bool fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev
unsigned short status;
unsigned int index, buflen, estatus;
+ if (fep->start_ns) {
+ unsigned delta = sched_clock() - fep->start_ns;
+ if (start_latency == 0 && delta < 1000000)
+ WARN_ON(1);
+ if (delta < 1000000)
+ start_latency += delta;
+ fep->start_ns = 0;
+ }
+
/* Protocol checksum off-load for TCP and UDP. */
if (fec_enet_clear_csum(skb, ndev))
return false;
@@ -576,8 +589,10 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_OK;
}
- if (ring_free(fep->tx_next, fep->tx_dirty, fep->tx_ring_size) < fep->tx_min)
+ if (ring_free(fep->tx_next, fep->tx_dirty, fep->tx_ring_size) < fep->tx_min) {
+ fep->stop_ns = sched_clock();
netif_stop_queue(ndev);
+ }
return NETDEV_TX_OK;
}
@@ -979,8 +994,15 @@ fec_enet_tx(struct net_device *ndev)
if (netif_queue_stopped(ndev) &&
ring_free(fep->tx_next, fep->tx_dirty, fep->tx_ring_size) >=
- fep->tx_min)
+ fep->tx_min) {
+ total_stopped += sched_clock() - fep->stop_ns;
+ if (start_latency == 0) {
+// WARN_ON(1);
+extern int __trace2; __trace2 = 1;
+ }
netif_wake_queue(ndev);
+ fep->start_ns = sched_clock();
+ }
}
static void
@@ -1006,7 +1028,7 @@ fec_enet_receive(struct sk_buff *skb, union bufdesc_u *bdp, struct net_device *n
napi_gro_receive(&fep->napi, skb);
}
-static void
+static void noinline
fec_enet_receive_copy(unsigned pkt_len, unsigned index, union bufdesc_u *bdp, struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1076,7 +1098,7 @@ fec_enet_receive_copy(unsigned pkt_len, unsigned index, union bufdesc_u *bdp, st
fec_enet_receive(skb, bdp, ndev);
}
-static void
+static void noinline
fec_enet_receive_nocopy(unsigned pkt_len, unsigned index, union bufdesc_u *bdp,
struct net_device *ndev)
{
@@ -1143,11 +1165,10 @@ fec_enet_receive_nocopy(unsigned pkt_len, unsigned index, union bufdesc_u *bdp,
* not been given to the system, we just set the empty indicator,
* effectively tossing the packet.
*/
-static int
+static int noinline
fec_enet_rx(struct net_device *ndev, int budget)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- ushort pkt_len;
int pkt_received = 0;
unsigned int index = fep->rx_next;
@@ -1160,7 +1181,7 @@ fec_enet_rx(struct net_device *ndev, int budget)
*/
do {
union bufdesc_u *bdp = fec_enet_rx_get(index, fep);
- unsigned status;
+ unsigned status, pkt_len;
status = bdp->bd.cbd_sc;
if (status & BD_ENET_RX_EMPTY)
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 5918d227730f..65a6d6ff15dc 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -222,7 +222,7 @@ static inline void lockdep_softirq_end(bool in_hardirq)
static inline bool lockdep_softirq_start(void) { return false; }
static inline void lockdep_softirq_end(bool in_hardirq) { }
#endif
-
+int __trace2;
asmlinkage __visible void __do_softirq(void)
{
unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
@@ -259,7 +259,7 @@ restart:
int prev_count;
h += softirq_bit - 1;
-
+if (__trace2) printk("%s: running %pf\n", __func__, h->action);
vec_nr = h - softirq_vec;
prev_count = preempt_count();
@@ -282,6 +282,8 @@ restart:
local_irq_disable();
pending = local_softirq_pending();
+if (__trace2)
+ printk("%s: pending=0x%08x\n", __func__, pending);
if (pending) {
if (time_before(jiffies, end) && !need_resched() &&
--max_restart)
@@ -289,7 +291,10 @@ restart:
wakeup_softirqd();
}
-
+if (__trace2)
+ printk("%s: pending=0x%08x jiffies=%lu end=%lu nrs=%u restart=%d\n",
+ __func__, pending, jiffies, end, need_resched(), max_restart);
+__trace2 = 0;
lockdep_softirq_end(in_hardirq);
account_irq_exit_time(current);
__local_bh_enable(SOFTIRQ_OFFSET);