Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5623255imu; Mon, 26 Nov 2018 03:08:41 -0800 (PST) X-Google-Smtp-Source: AFSGD/W3cSbtsFmMo+UQcdY5F9MtHzff1EbcWizeuiHCx32sfSOnbek7rKFjijgnBP7za4SXc3Xo X-Received: by 2002:a63:d5e:: with SMTP id 30mr24471603pgn.54.1543230521350; Mon, 26 Nov 2018 03:08:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543230521; cv=none; d=google.com; s=arc-20160816; b=feVFMQsgDnOa/ATwYqaiPWyef+mCqL/SP64RpIFRc3MlZCgF4fGGYh5F6i02HCXWB5 RLpgJJjvR4vMyfa74lVTOqeOfa7BvnBJxmWwAsjh5YTDh6VEKhOJbWcfQeNiQSodrnFy VRms7ItNWF/fbeVaY5aSVdazRWHo5jAVfY5Y7cCLey6wUFGg9jDEbXlrZbP4NJZzzQJJ /q1vLdiuZljrrYmIJ9Xe3hTW87vGOxehKkL3BeHFn/h7kPco4ystKAipxofyeKOBg+jw 1xX5k5S/6jJPMOLwMju8TJpVOMg9j0KvOpEzO00H+gZWroE7ZP7JCSdpB9o7TRiFd4G+ ntUA== 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=6iNR/l+nARZYdOxoc1jQ3OgemNiZDHPnUqFHVzqzT9U=; b=cBm7/l7A+KwMi7czPHSOJ5iP3VIndQcZqeZr2BGw9c6qJLKYzbZToGQjUcjr411UPv d9DomP1MRibDKjeHfivOcWUtT2HBSBRZtWnJ+mFIJlRYiFWoanxakwGpo0nQKS0eS8+l Ofe5OK6wWHhJfyoicMci3oQ9KkNm2CP4zTnqQlQDChGiSuFRV76WgCHBt1kbCEkIpwxv sZTeRP176xj2KawuBJoi2DZ0Ag/s+BP0q+sUzndg8mxV7DQJrviR1EAYhenS8QfV79k4 BhPUEja4oap547ZcEsWfx0K8K/ia3mspfqrzeDSUq6x0JyzQuv1DTrEmZviKjOok5xWL Fsrg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=QqyH4RoJ; 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 s13si30105863pgc.509.2018.11.26.03.08.27; Mon, 26 Nov 2018 03:08:41 -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=QqyH4RoJ; 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 S1731580AbeKZWAP (ORCPT + 99 others); Mon, 26 Nov 2018 17:00:15 -0500 Received: from mail.kernel.org ([198.145.29.99]:46996 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729543AbeKZWAO (ORCPT ); Mon, 26 Nov 2018 17:00:14 -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 40AF320645; Mon, 26 Nov 2018 11:06:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543230387; bh=ViPrb8JsQd9qJMiibI2QUpi6zli7IOAC9W1tKK35cTg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QqyH4RoJB0DqD4itHkmGoDrHi7jzrq5qs4L+Vs07B0co6zf7Agn6maQnQK8gHftJJ DNZlMcQGnhZgt5WwQqmUEZjvAlzDE959Wx2/PBAZzfwrK4mXXRSF1xqOSxhSsNxvLa DO5u1WuHIef6Jvw/ovFb/Y4BeWK94mRyxvYSvYW4= 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.19 082/118] qed: Fix blocking/unlimited SPQ entries leak Date: Mon, 26 Nov 2018 11:51:16 +0100 Message-Id: <20181126105104.987936772@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181126105059.832485122@linuxfoundation.org> References: <20181126105059.832485122@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.19-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 e95431f6acd4..04259df8a5c2 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 1673fc90027f..43619b6bb232 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_spq.c +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c @@ -685,6 +685,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; } @@ -768,6 +770,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) { @@ -825,11 +846,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) @@ -843,7 +865,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 */ @@ -875,25 +897,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; @@ -932,11 +937,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