diff options
-rw-r--r-- | arch/arm/mm/fault.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fec.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 35 | ||||
-rw-r--r-- | kernel/softirq.c | 11 |
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); |