From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-0016ce01.pphosted.com (mx0b-0016ce01.pphosted.com [67.231.156.153]) by dpdk.org (Postfix) with ESMTP id AC3C7803B for ; Wed, 19 Oct 2016 06:13:14 +0200 (CEST) Received: from pps.filterd (m0085408.ppops.net [127.0.0.1]) by mx0b-0016ce01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u9J4CYDY032274; Tue, 18 Oct 2016 21:13:12 -0700 Received: from avcashub1.qlogic.com ([198.186.0.117]) by mx0b-0016ce01.pphosted.com with ESMTP id 263keq5bmy-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 18 Oct 2016 21:13:12 -0700 Received: from avluser05.qlc.com (10.1.113.115) by qlc.com (10.1.4.192) with Microsoft SMTP Server id 14.3.235.1; Tue, 18 Oct 2016 21:13:11 -0700 Received: (from rmody@localhost) by avluser05.qlc.com (8.14.4/8.14.4/Submit) id u9J4DBVG002292; Tue, 18 Oct 2016 21:13:11 -0700 X-Authentication-Warning: avluser05.qlc.com: rmody set sender to rasesh.mody@qlogic.com using -f From: Rasesh Mody To: , , CC: , , Harish Patil Date: Tue, 18 Oct 2016 21:11:23 -0700 Message-ID: <1476850306-2141-10-git-send-email-rasesh.mody@qlogic.com> X-Mailer: git-send-email 1.7.10.3 In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com> References: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com> MIME-Version: 1.0 Content-Type: text/plain disclaimer: bypass X-Proofpoint-Virus-Version: vendor=nai engine=5800 definitions=8322 signatures=670725 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609300000 definitions=main-1610190074 Subject: [dpdk-dev] [PATCH v4 09/32] net/qede: serialize access to MFW mbox X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Oct 2016 04:13:15 -0000 From: Harish Patil Add ecore_mcp_mb_lock() and ecore_mcp_mb_unlock() APIs to ensure a single thread is accessing MFW mailbox. Signed-off-by: Harish Patil --- drivers/net/qede/base/ecore_mcp.c | 70 ++++++++++++++++++++++++++++++++++----- drivers/net/qede/base/ecore_mcp.h | 4 +++ 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index 24211a3..12e1ec1 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -202,6 +202,51 @@ err: return ECORE_NOMEM; } +/* Locks the MFW mailbox of a PF to ensure a single access. + * The lock is achieved in most cases by holding a spinlock, causing other + * threads to wait till a previous access is done. + * In some cases (currently when a [UN]LOAD_REQ commands are sent), the single + * access is achieved by setting a blocking flag, which will fail other + * competing contexts to send their mailboxes. + */ +static enum _ecore_status_t ecore_mcp_mb_lock(struct ecore_hwfn *p_hwfn, + u32 cmd) +{ + OSAL_SPIN_LOCK(&p_hwfn->mcp_info->lock); + + /* The spinlock shouldn't be acquired when the mailbox command is + * [UN]LOAD_REQ, since the engine is locked by the MFW, and a parallel + * pending [UN]LOAD_REQ command of another PF together with a spinlock + * (i.e. interrupts are disabled) - can lead to a deadlock. + * It is assumed that for a single PF, no other mailbox commands can be + * sent from another context while sending LOAD_REQ, and that any + * parallel commands to UNLOAD_REQ can be cancelled. + */ + if (cmd == DRV_MSG_CODE_LOAD_DONE || cmd == DRV_MSG_CODE_UNLOAD_DONE) + p_hwfn->mcp_info->block_mb_sending = false; + + if (p_hwfn->mcp_info->block_mb_sending) { + DP_NOTICE(p_hwfn, false, + "Trying to send a MFW mailbox command [0x%x] in parallel to [UN]LOAD_REQ. Aborting.\n", + cmd); + OSAL_SPIN_UNLOCK(&p_hwfn->mcp_info->lock); + return ECORE_BUSY; + } + + if (cmd == DRV_MSG_CODE_LOAD_REQ || cmd == DRV_MSG_CODE_UNLOAD_REQ) { + p_hwfn->mcp_info->block_mb_sending = true; + OSAL_SPIN_UNLOCK(&p_hwfn->mcp_info->lock); + } + + return ECORE_SUCCESS; +} + +static void ecore_mcp_mb_unlock(struct ecore_hwfn *p_hwfn, u32 cmd) +{ + if (cmd != DRV_MSG_CODE_LOAD_REQ && cmd != DRV_MSG_CODE_UNLOAD_REQ) + OSAL_SPIN_UNLOCK(&p_hwfn->mcp_info->lock); +} + enum _ecore_status_t ecore_mcp_reset(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) { @@ -214,8 +259,12 @@ enum _ecore_status_t ecore_mcp_reset(struct ecore_hwfn *p_hwfn, if (CHIP_REV_IS_EMUL(p_hwfn->p_dev)) delay = EMUL_MCP_RESP_ITER_US; #endif - - OSAL_SPIN_LOCK(&p_hwfn->mcp_info->lock); + /* Ensure that only a single thread is accessing the mailbox at a + * certain time. + */ + rc = ecore_mcp_mb_lock(p_hwfn, DRV_MSG_CODE_MCP_RESET); + if (rc != ECORE_SUCCESS) + return rc; /* Set drv command along with the updated sequence */ org_mcp_reset_seq = ecore_rd(p_hwfn, p_ptt, MISCS_REG_GENERIC_POR_0); @@ -238,7 +287,7 @@ enum _ecore_status_t ecore_mcp_reset(struct ecore_hwfn *p_hwfn, rc = ECORE_AGAIN; } - OSAL_SPIN_UNLOCK(&p_hwfn->mcp_info->lock); + ecore_mcp_mb_unlock(p_hwfn, DRV_MSG_CODE_MCP_RESET); return rc; } @@ -327,14 +376,16 @@ ecore_mcp_cmd_and_union(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, return ECORE_BUSY; } - /* Acquiring a spinlock is needed to ensure that only a single thread - * is accessing the mailbox at a certain time. - */ - OSAL_SPIN_LOCK(&p_hwfn->mcp_info->lock); - union_data_addr = p_hwfn->mcp_info->drv_mb_addr + OFFSETOF(struct public_drv_mb, union_data); + /* Ensure that only a single thread is accessing the mailbox at a + * certain time. + */ + rc = ecore_mcp_mb_lock(p_hwfn, p_mb_params->cmd); + if (rc != ECORE_SUCCESS) + return rc; + if (p_mb_params->p_data_src != OSAL_NULL) ecore_memcpy_to(p_hwfn, p_ptt, union_data_addr, p_mb_params->p_data_src, @@ -348,6 +399,9 @@ ecore_mcp_cmd_and_union(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, ecore_memcpy_from(p_hwfn, p_ptt, p_mb_params->p_data_dst, union_data_addr, sizeof(*p_mb_params->p_data_dst)); + + ecore_mcp_mb_unlock(p_hwfn, p_mb_params->cmd); + return rc; } diff --git a/drivers/net/qede/base/ecore_mcp.h b/drivers/net/qede/base/ecore_mcp.h index 28a8f93..e055835 100644 --- a/drivers/net/qede/base/ecore_mcp.h +++ b/drivers/net/qede/base/ecore_mcp.h @@ -32,6 +32,10 @@ ((_p_hwfn)->p_dev->num_ports_in_engines * 2)) struct ecore_mcp_info { osal_spinlock_t lock; /* Spinlock used for accessing MCP mailbox */ + + /* Flag to indicate whether sending a MFW mailbox is forbidden */ + bool block_mb_sending; + u32 public_base; /* Address of the MCP public area */ u32 drv_mb_addr; /* Address of the driver mailbox */ u32 mfw_mb_addr; /* Address of the MFW mailbox */ -- 1.8.3.1