From patchwork Thu Jun 18 10:05:54 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sathya Perla X-Patchwork-Id: 28852 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 1C340B725C for ; Thu, 18 Jun 2009 20:06:28 +1000 (EST) Received: by ozlabs.org (Postfix) id 0BB48DDDA1; Thu, 18 Jun 2009 20:06:28 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 7F8E9DDDA0 for ; Thu, 18 Jun 2009 20:06:27 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755436AbZFRKGT (ORCPT ); Thu, 18 Jun 2009 06:06:19 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753874AbZFRKGS (ORCPT ); Thu, 18 Jun 2009 06:06:18 -0400 Received: from segment-124-30.sify.net ([124.30.166.146]:13924 "EHLO sperla-laptop.localdomain" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1751970AbZFRKGS (ORCPT ); Thu, 18 Jun 2009 06:06:18 -0400 Received: by sperla-laptop.localdomain (Postfix, from userid 1000) id BF21217EA1D; Thu, 18 Jun 2009 15:35:54 +0530 (IST) Date: Thu, 18 Jun 2009 15:35:54 +0530 From: Sathya Perla To: netdev Subject: [net-next PATCH 2/4] be2net: Use MCC queue for cmds that may be called in BH context Message-ID: <20090618100554.GA12685@serverengines.com> Reply-To: Sathya Perla Mail-Followup-To: netdev MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currenlty multicast_set and promiscuous_config cmds -- that may be called in BH context -- use the blocking MCC mbox to post cmds. An mbox cmd is protected via a spin_lock(cmd_lock) and not spin_lock_bh() as it is undesirable to disable BHs while a blocking mbox cmd is in progress (and take long to finish.) This can lockup a cmd in progress in process context. So, these two cmds in BH context must use the MCC queue to post cmds. Signed-off-by: Sathya Perla --- drivers/net/benet/be_cmds.c | 69 ++++++++++++++++++++++++++++++++---------- 1 files changed, 52 insertions(+), 17 deletions(-) diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index f1ec191..0b60508 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -17,7 +17,7 @@ #include "be.h" -void be_mcc_notify(struct be_ctrl_info *ctrl) +static void be_mcc_notify(struct be_ctrl_info *ctrl) { struct be_queue_info *mccq = &ctrl->mcc_obj.q; u32 val = 0; @@ -101,6 +101,28 @@ void be_process_mcc(struct be_ctrl_info *ctrl) spin_unlock_bh(&ctrl->mcc_cq_lock); } +/* Wait till no more pending mcc requests are present */ +static void be_mcc_wait_compl(struct be_ctrl_info *ctrl) +{ +#define mcc_timeout 50000 /* 5s timeout */ + int i; + for (i = 0; i < mcc_timeout; i++) { + be_process_mcc(ctrl); + if (atomic_read(&ctrl->mcc_obj.q.used) == 0) + break; + udelay(100); + } + if (i == mcc_timeout) + printk(KERN_WARNING DRV_NAME "mcc poll timed out\n"); +} + +/* Notify MCC requests and wait for completion */ +static void be_mcc_notify_wait(struct be_ctrl_info *ctrl) +{ + be_mcc_notify(ctrl); + be_mcc_wait_compl(ctrl); +} + static int be_mbox_db_ready_wait(void __iomem *db) { int cnt = 0, wait = 5; @@ -872,14 +894,18 @@ int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, u16 *vtag_array, return status; } +/* Use MCC for this command as it may be called in BH context */ int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_promiscuous_config *req = embedded_payload(wrb); - int status; + struct be_mcc_wrb *wrb; + struct be_cmd_req_promiscuous_config *req; - spin_lock(&ctrl->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + spin_lock_bh(&ctrl->mcc_lock); + + wrb = wrb_from_mcc(&ctrl->mcc_obj.q); + BUG_ON(!wrb); + + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -891,21 +917,29 @@ int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en) else req->port0_promiscuous = en; - status = be_mbox_db_ring(ctrl); + be_mcc_notify_wait(ctrl); - spin_unlock(&ctrl->mbox_lock); - return status; + spin_unlock_bh(&ctrl->mcc_lock); + return 0; } +/* + * Use MCC for this command as it may be called in BH context + * (mc == NULL) => multicast promiscous + */ int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table, u32 num, bool promiscuous) { - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_req_mcast_mac_config *req = embedded_payload(wrb); - int status; +#define BE_MAX_MC 32 /* set mcast promisc if > 32 */ + struct be_mcc_wrb *wrb; + struct be_cmd_req_mcast_mac_config *req; - spin_lock(&ctrl->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); + spin_lock_bh(&ctrl->mcc_lock); + + wrb = wrb_from_mcc(&ctrl->mcc_obj.q); + BUG_ON(!wrb); + + req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -920,10 +954,11 @@ int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table, memcpy(req->mac, mac_table, ETH_ALEN * num); } - status = be_mbox_db_ring(ctrl); + be_mcc_notify_wait(ctrl); - spin_unlock(&ctrl->mbox_lock); - return status; + spin_unlock_bh(&ctrl->mcc_lock); + + return 0; } int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc)