From patchwork Mon Apr 13 21:02:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 460944 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id A1F621401AB for ; Tue, 14 Apr 2015 07:02:50 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964785AbbDMVCb (ORCPT ); Mon, 13 Apr 2015 17:02:31 -0400 Received: from www.linutronix.de ([62.245.132.108]:33742 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932648AbbDMVC2 (ORCPT ); Mon, 13 Apr 2015 17:02:28 -0400 Received: from localhost ([127.0.0.1] helo=[127.0.1.1]) by Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1YhlUW-0002PB-9m; Mon, 13 Apr 2015 23:02:00 +0200 Message-Id: <20150413210035.274411419@linutronix.de> User-Agent: quilt/0.63-1 Date: Mon, 13 Apr 2015 21:02:23 -0000 From: Thomas Gleixner To: LKML Cc: Peter Zijlstra , Ingo Molnar , "David S. Miller" , dingtianhong , Arnd Bergmann , Zhangfei Gao , Dan Carpenter , netdev@vger.kernel.org Subject: [patch 4/5] net: hip04: Make tx coalesce timer actually work References: <20150413210009.682000343@linutronix.de> MIME-Version: 1.0 Content-Disposition: inline; filename=net-hip04-fix-hrtimer-wreckage.patch X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1, SHORTCIRCUIT=-0.0001, URIBL_BLOCKED=0.001 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The code sets the expiry value of the timer to a relative value and starts it with hrtimer_start_expires. That's fine, but that only works once. The timer is started in relative mode, so the expiry value gets overwritten with the absolut expiry time (now + expiry). So once the timer expired, a new call to hrtimer_start_expires results in an immidiately expired timer, because the expiry value is already in the past. Use the proper mechanisms to (re)start the timer in the intended way. Signed-off-by: Thomas Gleixner Cc: "David S. Miller" Cc: dingtianhong Cc: Arnd Bergmann Cc: Zhangfei Gao Cc: Dan Carpenter Cc: netdev@vger.kernel.org --- drivers/net/ethernet/hisilicon/hip04_eth.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux/drivers/net/ethernet/hisilicon/hip04_eth.c =================================================================== --- linux.orig/drivers/net/ethernet/hisilicon/hip04_eth.c +++ linux/drivers/net/ethernet/hisilicon/hip04_eth.c @@ -413,6 +413,15 @@ out: return count; } +static void hip04_start_tx_timer(struct hip04_priv *priv) +{ + ktime_t t; + + /* allow timer to fire after half the time at the earliest */ + t = ktime_set(0, priv->tx_coalesce_usecs * NSEC_PER_USEC / 2); + hrtimer_start(&priv->tx_coalesce_timer, t, HRTIMER_MODE_REL); +} + static int hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev) { struct hip04_priv *priv = netdev_priv(ndev); @@ -466,8 +475,7 @@ static int hip04_mac_start_xmit(struct s } } else if (!hrtimer_is_queued(&priv->tx_coalesce_timer)) { /* cleanup not pending yet, start a new timer */ - hrtimer_start_expires(&priv->tx_coalesce_timer, - HRTIMER_MODE_REL); + hip04_start_tx_timer(priv); } return NETDEV_TX_OK; @@ -549,7 +557,7 @@ done: /* clean up tx descriptors and start a new timer if necessary */ tx_remaining = hip04_tx_reclaim(ndev, false); if (rx < budget && tx_remaining) - hrtimer_start_expires(&priv->tx_coalesce_timer, HRTIMER_MODE_REL); + hip04_start_tx_timer(priv); return rx; } @@ -809,7 +817,6 @@ static int hip04_mac_probe(struct platfo struct hip04_priv *priv; struct resource *res; unsigned int irq; - ktime_t txtime; int ret; ndev = alloc_etherdev(sizeof(struct hip04_priv)); @@ -846,9 +853,6 @@ static int hip04_mac_probe(struct platfo */ priv->tx_coalesce_frames = TX_DESC_NUM * 3 / 4; priv->tx_coalesce_usecs = 200; - /* allow timer to fire after half the time at the earliest */ - txtime = ktime_set(0, priv->tx_coalesce_usecs * NSEC_PER_USEC / 2); - hrtimer_set_expires_range(&priv->tx_coalesce_timer, txtime, txtime); priv->tx_coalesce_timer.function = tx_done; priv->map = syscon_node_to_regmap(arg.np);