From patchwork Fri Apr 3 20:27:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kirsher, Jeffrey T" X-Patchwork-Id: 458036 X-Patchwork-Delegate: jeffrey.t.kirsher@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from fraxinus.osuosl.org (fraxinus.osuosl.org [140.211.166.137]) by ozlabs.org (Postfix) with ESMTP id 6FA541400B7 for ; Sat, 4 Apr 2015 07:27:25 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id BA00EA40AF; Fri, 3 Apr 2015 20:27:24 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PFMy-8oKGwAv; Fri, 3 Apr 2015 20:27:23 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by fraxinus.osuosl.org (Postfix) with ESMTP id DCCE9A3502; Fri, 3 Apr 2015 20:27:22 +0000 (UTC) X-Original-To: intel-wired-lan@lists.osuosl.org Delivered-To: intel-wired-lan@lists.osuosl.org Received: from whitealder.osuosl.org (whitealder.osuosl.org [140.211.166.138]) by ash.osuosl.org (Postfix) with ESMTP id DF48B1C107C for ; Fri, 3 Apr 2015 20:27:21 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id DD4CA9214E for ; Fri, 3 Apr 2015 20:27:21 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7UIWjXLcVrJX for ; Fri, 3 Apr 2015 20:27:21 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by whitealder.osuosl.org (Postfix) with ESMTP id 74BC192163 for ; Fri, 3 Apr 2015 20:27:21 +0000 (UTC) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP; 03 Apr 2015 13:27:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,519,1422950400"; d="scan'208";a="476517926" Received: from lwang4-mobl1.amr.corp.intel.com (HELO jtkirshe-mobl.amr.corp.intel.com) ([10.254.109.203]) by FMSMGA003.fm.intel.com with ESMTP; 03 Apr 2015 13:27:21 -0700 From: Jeff Kirsher To: intel-wired-lan@lists.osuosl.org Date: Fri, 3 Apr 2015 13:27:05 -0700 Message-Id: <1428092835-16834-15-git-send-email-jeffrey.t.kirsher@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1428092835-16834-1-git-send-email-jeffrey.t.kirsher@intel.com> References: <1428092835-16834-1-git-send-email-jeffrey.t.kirsher@intel.com> Subject: [Intel-wired-lan] [net-next 15/25] fm10k: use separate workqueue for fm10k driver X-BeenThere: intel-wired-lan@lists.osuosl.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Intel Wired Ethernet Linux Kernel Driver Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-wired-lan-bounces@lists.osuosl.org Sender: "Intel-wired-lan" Since we run the watchdog periodically, which might take a while and potentially monopolize the system default workqueue, create our own separate work queue. This also helps reduce and stabilize latency between scheduling the work in our interrupt and actually performing the work. Still use a timer for the regular scheduled interval but queue the work onto its own work queue. It seemed overkill to create a single workqueue per interface, so we just spawn a single work queue for all interfaces upon driver load. For this reason, use a multi-threaded workqueue with one thread per processor, rather than single threaded queue. Signed-off-by: Jeff Kirsher Signed-off-by: Jacob Keller Acked-by: Matthew Vick Tested-by: Krishneil Singh --- drivers/net/ethernet/intel/fm10k/fm10k.h | 3 +++ drivers/net/ethernet/intel/fm10k/fm10k_main.c | 12 ++++++++++++ drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/fm10k/fm10k.h b/drivers/net/ethernet/intel/fm10k/fm10k.h index 715d0a0..cc7f442e 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k.h +++ b/drivers/net/ethernet/intel/fm10k/fm10k.h @@ -235,6 +235,9 @@ struct fm10k_vxlan_port { __be16 port; }; +/* one work queue for entire driver */ +extern struct workqueue_struct *fm10k_workqueue; + struct fm10k_intfc { unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; struct net_device *netdev; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index 5022a45..1e08832 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c @@ -41,6 +41,9 @@ MODULE_DESCRIPTION("Intel(R) Ethernet Switch Host Interface Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +/* single workqueue for entire fm10k driver */ +struct workqueue_struct *fm10k_workqueue = NULL; + /** * fm10k_init_module - Driver Registration Routine * @@ -52,6 +55,10 @@ static int __init fm10k_init_module(void) pr_info("%s - version %s\n", fm10k_driver_string, fm10k_driver_version); pr_info("%s\n", fm10k_copyright); + /* create driver workqueue */ + if (!fm10k_workqueue) + fm10k_workqueue = create_workqueue("fm10k"); + fm10k_dbg_init(); return fm10k_register_pci_driver(); @@ -69,6 +76,11 @@ static void __exit fm10k_exit_module(void) fm10k_unregister_pci_driver(); fm10k_dbg_exit(); + + /* destroy driver workqueue */ + flush_workqueue(fm10k_workqueue); + destroy_workqueue(fm10k_workqueue); + fm10k_workqueue = NULL; } module_exit(fm10k_exit_module); diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c index d7af466..fcf0d5a 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c @@ -94,7 +94,7 @@ void fm10k_service_event_schedule(struct fm10k_intfc *interface) { if (!test_bit(__FM10K_SERVICE_DISABLE, &interface->state) && !test_and_set_bit(__FM10K_SERVICE_SCHED, &interface->state)) - schedule_work(&interface->service_task); + queue_work(fm10k_workqueue, &interface->service_task); } static void fm10k_service_event_complete(struct fm10k_intfc *interface)