From patchwork Mon Apr 22 11:56:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Vadai X-Patchwork-Id: 238488 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 7D12E2C014B for ; Mon, 22 Apr 2013 22:02:15 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752401Ab3DVMCC (ORCPT ); Mon, 22 Apr 2013 08:02:02 -0400 Received: from eu1sys200aog101.obsmtp.com ([207.126.144.111]:58143 "EHLO eu1sys200aog101.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752262Ab3DVMCA (ORCPT ); Mon, 22 Apr 2013 08:02:00 -0400 Received: from l-coreslave.lab.mtl.com ([82.166.227.17]) (using TLSv1) by eu1sys200aob101.postini.com ([207.126.147.11]) with SMTP ID DSNKUXUmstEGHBXUE3VL9MD4WfrryE3DU465@postini.com; Mon, 22 Apr 2013 12:02:00 UTC Received: from vnc15.mtl.labs.mlnx (vnc15.mtl.labs.mlnx [10.7.2.15]) by l-coreslave.lab.mtl.com (8.13.8/8.13.8) with ESMTP id r3MC1q9N001705; Mon, 22 Apr 2013 15:01:54 +0300 From: Amir Vadai To: "David S. Miller" Cc: netdev@vger.kernel.org, Richard Cochran , Or Gerlitz , Eugenia Emantayev , Amir Vadai Subject: [PATCH net-next V2 5/5] net/mlx4_en: Add a service task Date: Mon, 22 Apr 2013 14:56:07 +0300 Message-Id: <1366631767-16493-6-git-send-email-amirv@mellanox.com> X-Mailer: git-send-email 1.7.8.2 In-Reply-To: <1366631767-16493-1-git-send-email-amirv@mellanox.com> References: <1366631767-16493-1-git-send-email-amirv@mellanox.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add a service task to run tasks that needed to be executed periodically. Currently the only task is a watchdog to catch NIC clock overflow, to make timestamping accurate. Will move the statistics task into this framework in a later patch. Signed-off-by: Amir Vadai --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 20 ++++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 24 ++++++++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 4 ++++ 3 files changed, 48 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 6d8227d..c1982a4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -126,4 +126,24 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) timecounter_init(&mdev->clock, &mdev->cycles, ktime_to_ns(ktime_get_real())); + + /* Calculate period in seconds to call the overflow watchdog. Doing + * that, by dividing the maximal cycles value in nano-seconds, convert + * it to seconds, and divide by 2 - to make sure counter is checked at + * least once every wrap around. + */ + mdev->overflow_period = + cyclecounter_cyc2ns(&mdev->cycles, + mdev->cycles.mask) / 1000000 / 2; +} + +void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev) +{ + bool timeout = time_is_before_jiffies(mdev->last_overflow_check + + HZ * mdev->overflow_period); + + if (timeout) { + timecounter_read(&mdev->clock); + mdev->last_overflow_check = jiffies; + } } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 4cb9f32..f4f88b8 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1361,6 +1361,26 @@ static void mlx4_en_do_get_stats(struct work_struct *work) mutex_unlock(&mdev->state_lock); } +/* mlx4_en_service_task - Run service task for tasks that needed to be done + * periodically + */ +static void mlx4_en_service_task(struct work_struct *work) +{ + struct delayed_work *delay = to_delayed_work(work); + struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv, + service_task); + struct mlx4_en_dev *mdev = priv->mdev; + + mutex_lock(&mdev->state_lock); + if (mdev->device_up) { + mlx4_en_ptp_overflow_check(mdev); + + queue_delayed_work(mdev->workqueue, &priv->service_task, + SERVICE_TASK_DELAY); + } + mutex_unlock(&mdev->state_lock); +} + static void mlx4_en_linkstate(struct work_struct *work) { struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, @@ -1865,6 +1885,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev) mlx4_free_hwq_res(mdev->dev, &priv->res, MLX4_EN_PAGE_SIZE); cancel_delayed_work(&priv->stats_task); + cancel_delayed_work(&priv->service_task); /* flush any pending task for this netdev */ flush_workqueue(mdev->workqueue); @@ -2084,6 +2105,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, INIT_WORK(&priv->watchdog_task, mlx4_en_restart); INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); + INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task); #ifdef CONFIG_MLX4_EN_DCB if (!mlx4_is_slave(priv->mdev->dev)) { if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_SET_ETH_SCHED) { @@ -2206,6 +2228,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, } mlx4_en_set_default_moderation(priv); queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); + queue_delayed_work(mdev->workqueue, &priv->service_task, + SERVICE_TASK_DELAY); return 0; out: diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 85b0754..f4b61c5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -78,6 +78,7 @@ #define STAMP_SHIFT 31 #define STAMP_VAL 0x7fffffff #define STATS_DELAY (HZ / 4) +#define SERVICE_TASK_DELAY (HZ / 4) #define MAX_NUM_OF_FS_RULES 256 #define MLX4_EN_FILTER_HASH_SHIFT 4 @@ -355,6 +356,7 @@ struct mlx4_en_dev { struct cyclecounter cycles; struct timecounter clock; unsigned long last_overflow_check; + u32 overflow_period; }; @@ -519,6 +521,7 @@ struct mlx4_en_priv { struct work_struct watchdog_task; struct work_struct linkstate_task; struct delayed_work stats_task; + struct delayed_work service_task; struct mlx4_en_perf_stats pstats; struct mlx4_en_pkt_stats pkstats; struct mlx4_en_port_stats port_stats; @@ -645,6 +648,7 @@ void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv, #define MLX4_EN_NUM_SELF_TEST 5 void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf); u64 mlx4_en_mac_to_u64(u8 *addr); +void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev); /* * Functions for time stamping