Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5616938imu; Mon, 26 Nov 2018 03:04:09 -0800 (PST) X-Google-Smtp-Source: AFSGD/UGp01wpfoDyMec5CNQ102wtJKJqrvpsCcGGkCNwwF/FxFPq2OnDBBeXNKhn4uok4qhTnjI X-Received: by 2002:a17:902:a83:: with SMTP id 3mr21842545plp.276.1543230249564; Mon, 26 Nov 2018 03:04:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543230249; cv=none; d=google.com; s=arc-20160816; b=SlAiD0yluAWs6Kvj/vFjD4KSXOTwJmsIwD7EODeYcR9+EWcJZyN+dBvYPMA7oJKfHt cCgi9VTjWPpiZWthtutN7cfsGJEsEwsExEeNZWz7hcNtQ2F0+LC5vSaUvwubIeMkLZzN r+keuP7bJKroGqWkkHRtjMLLsis+faPHL5LkGiXawBREt8JzPax+xEwxDbi8nvGa6Ruq RHBzchAWicuosDpYPjcfLgMq+1VOtpsm6bQYOyMza9z8aVTKzPHg+2gpbr+4+uqp2poq 2KMiSYTRkFmlRvSn6RfiMlOniBVzuh4gr+p+hTJVUeaaOyLmdWopFbD6f3hMyjy5xCEl NbPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=jpnoLLHDrppeM6bc0srExjgC+olvvZJ3PLI35zDrRQ4=; b=ERePofGSKnmlPx18rfrGeycBQIQsa/OOFjv89n8xq+e9KL70RwrufuzydAeAL1PXP/ BfGgv5+nbXpLE0IduIJz+NzodSHKwIrWuKIWW7JI1fQBaIKPp2cM3tivWjrMJSnL0a7E r8MkHDfg9gxopH/R86nTq0+698A6XIjNeNgv11yjwLsD1oIX3Z3htQqdRCCiICh0dlZz s8FlhoEUvyqu1L9cZ8xYUJnk8U8OE+4hREznJ28Vx6SLRjenMzqDPoYlkPN6yG161Y9m jKMVuqmlxNzp1I/+JkhHN4H9oCpoatC34ZxwnB0Ymi6oPW85WVH2rYKQ+aC/kRgZUDMx IG2Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=X8YF0hPr; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z8si16271514pgk.183.2018.11.26.03.03.54; Mon, 26 Nov 2018 03:04:09 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=X8YF0hPr; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730136AbeKZVzM (ORCPT + 99 others); Mon, 26 Nov 2018 16:55:12 -0500 Received: from mail.kernel.org ([198.145.29.99]:37656 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728901AbeKZVzL (ORCPT ); Mon, 26 Nov 2018 16:55:11 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 9B7092089F; Mon, 26 Nov 2018 11:01:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543230086; bh=hYqTkETKCJvuWXpd5fMMSrgqSBkmY+bS9/cAzFpqZQw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X8YF0hPrQMOUzUP2NSq3FclTePLPxbFk7JNZplgFEMDbNfn+cGc7KD1pbFh9u4P4g NM+EwxqrBbQ4xQWehdrNmRhVUUzDZnwSUSgavEwuFrkhchYKuuoboRKSAWlEIR4rCi txTqHXFRG+J351yvscaUXwQgVsIcEjt9MD6ac92E= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Denis Bolotin , Michal Kalderon , "David S. Miller" , Sasha Levin Subject: [PATCH 4.14 37/62] qed: Fix blocking/unlimited SPQ entries leak Date: Mon, 26 Nov 2018 11:51:18 +0100 Message-Id: <20181126105053.709722966@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181126105050.592727680@linuxfoundation.org> References: <20181126105050.592727680@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ [ Upstream commit 2632f22ebd08da249c2017962a199a0cfb2324bf ] When there are no SPQ entries left in the free_pool, new entries are allocated and are added to the unlimited list. When an entry in the pool is available, the content is copied from the original entry, and the new entry is sent to the device. qed_spq_post() is not aware of that, so the additional entry is stored in the original entry as p_post_ent, which can later be returned to the pool. Signed-off-by: Denis Bolotin Signed-off-by: Michal Kalderon Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/qlogic/qed/qed_sp.h | 3 ++ drivers/net/ethernet/qlogic/qed/qed_spq.c | 57 ++++++++++++----------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h b/drivers/net/ethernet/qlogic/qed/qed_sp.h index ab4ad8a1e2a5..01a213d4ee9c 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_sp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h @@ -167,6 +167,9 @@ struct qed_spq_entry { enum spq_mode comp_mode; struct qed_spq_comp_cb comp_cb; struct qed_spq_comp_done comp_done; /* SPQ_MODE_EBLOCK */ + + /* Posted entry for unlimited list entry in EBLOCK mode */ + struct qed_spq_entry *post_ent; }; struct qed_eq { diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c index be48d9abd001..0313e9c46979 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_spq.c +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c @@ -687,6 +687,8 @@ static int qed_spq_add_entry(struct qed_hwfn *p_hwfn, /* EBLOCK responsible to free the allocated p_ent */ if (p_ent->comp_mode != QED_SPQ_MODE_EBLOCK) kfree(p_ent); + else + p_ent->post_ent = p_en2; p_ent = p_en2; } @@ -770,6 +772,25 @@ static int qed_spq_pend_post(struct qed_hwfn *p_hwfn) SPQ_HIGH_PRI_RESERVE_DEFAULT); } +/* Avoid overriding of SPQ entries when getting out-of-order completions, by + * marking the completions in a bitmap and increasing the chain consumer only + * for the first successive completed entries. + */ +static void qed_spq_comp_bmap_update(struct qed_hwfn *p_hwfn, __le16 echo) +{ + u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE; + struct qed_spq *p_spq = p_hwfn->p_spq; + + __set_bit(pos, p_spq->p_comp_bitmap); + while (test_bit(p_spq->comp_bitmap_idx, + p_spq->p_comp_bitmap)) { + __clear_bit(p_spq->comp_bitmap_idx, + p_spq->p_comp_bitmap); + p_spq->comp_bitmap_idx++; + qed_chain_return_produced(&p_spq->chain); + } +} + int qed_spq_post(struct qed_hwfn *p_hwfn, struct qed_spq_entry *p_ent, u8 *fw_return_code) { @@ -821,11 +842,12 @@ int qed_spq_post(struct qed_hwfn *p_hwfn, p_ent->queue == &p_spq->unlimited_pending); if (p_ent->queue == &p_spq->unlimited_pending) { - /* This is an allocated p_ent which does not need to - * return to pool. - */ + struct qed_spq_entry *p_post_ent = p_ent->post_ent; + kfree(p_ent); - return rc; + + /* Return the entry which was actually posted */ + p_ent = p_post_ent; } if (rc) @@ -839,7 +861,7 @@ int qed_spq_post(struct qed_hwfn *p_hwfn, spq_post_fail2: spin_lock_bh(&p_spq->lock); list_del(&p_ent->list); - qed_chain_return_produced(&p_spq->chain); + qed_spq_comp_bmap_update(p_hwfn, p_ent->elem.hdr.echo); spq_post_fail: /* return to the free pool */ @@ -871,25 +893,8 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn, spin_lock_bh(&p_spq->lock); list_for_each_entry_safe(p_ent, tmp, &p_spq->completion_pending, list) { if (p_ent->elem.hdr.echo == echo) { - u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE; - list_del(&p_ent->list); - - /* Avoid overriding of SPQ entries when getting - * out-of-order completions, by marking the completions - * in a bitmap and increasing the chain consumer only - * for the first successive completed entries. - */ - __set_bit(pos, p_spq->p_comp_bitmap); - - while (test_bit(p_spq->comp_bitmap_idx, - p_spq->p_comp_bitmap)) { - __clear_bit(p_spq->comp_bitmap_idx, - p_spq->p_comp_bitmap); - p_spq->comp_bitmap_idx++; - qed_chain_return_produced(&p_spq->chain); - } - + qed_spq_comp_bmap_update(p_hwfn, echo); p_spq->comp_count++; found = p_ent; break; @@ -928,11 +933,9 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn, QED_MSG_SPQ, "Got a completion without a callback function\n"); - if ((found->comp_mode != QED_SPQ_MODE_EBLOCK) || - (found->queue == &p_spq->unlimited_pending)) + if (found->comp_mode != QED_SPQ_MODE_EBLOCK) /* EBLOCK is responsible for returning its own entry into the - * free list, unless it originally added the entry into the - * unlimited pending list. + * free list. */ qed_spq_return_entry(p_hwfn, found); -- 2.17.1