From patchwork Sat Jun 13 04:24:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Scott Feldman X-Patchwork-Id: 483813 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 781B21401AB for ; Sat, 13 Jun 2015 14:22:54 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=w8NOsL2Y; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751150AbbFMEWp (ORCPT ); Sat, 13 Jun 2015 00:22:45 -0400 Received: from mail-pa0-f50.google.com ([209.85.220.50]:35779 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750765AbbFMEWo (ORCPT ); Sat, 13 Jun 2015 00:22:44 -0400 Received: by pacyx8 with SMTP id yx8so32732323pac.2 for ; Fri, 12 Jun 2015 21:22:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=aaKMooL2yZn8rHgz5O46pb5uFgsEyLydcHC5S21oH3s=; b=w8NOsL2YoTtn/AbzKqHqgIIg5mPN2rdyY4qYS3r0qPFILZZL/v4UY1tL/oBQXUC0sm nThxUaS6zeLNJ2NA1uJqgzuhCVdii9B6FhHDLfqasuDDPFsO8zuMV2xPwyyz26Zl8nkH 79UFzNVhUQO5uNMA/MfACaOJGyeonLjW9rURRbKpbw7NfCXGVzGlS5eYIz98N5pGFJdF 0PjlmeoS05JxgCeQbdR0raW7WaS0WZ3Iwvx3kJrzlaP1IDqnAGC9uGtO0aGXxPHe3IBH v9AwTvHoHPoawXcb4EAVg1QhGbV3n8RQKnGiEYNtTY4s669KqG1asy/9cdModayr4iGR B2xQ== X-Received: by 10.66.148.34 with SMTP id tp2mr28511453pab.65.1434169363689; Fri, 12 Jun 2015 21:22:43 -0700 (PDT) Received: from rocker1.rocker.net ([199.58.98.143]) by mx.google.com with ESMTPSA id w1sm5121096pbs.35.2015.06.12.21.22.42 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 12 Jun 2015 21:22:43 -0700 (PDT) From: sfeldma@gmail.com To: netdev@vger.kernel.org Cc: jiri@resnulli.us, simon.horman@netronome.com, makita.toshiaki@lab.ntt.co.jp Subject: [PATCH net-next] rocker: fix neigh tbl index increment race Date: Fri, 12 Jun 2015 21:24:40 -0700 Message-Id: <1434169480-62863-1-git-send-email-sfeldma@gmail.com> X-Mailer: git-send-email 1.7.10.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Scott Feldman rocker->neigh_tbl_next_index is used to generate unique indices for neigh entries programmed into the device. The way new indices were generated was racy with the new prepare-commit transaction model. A simple fix here removes the race. The race was with two processes getting the same index, one process using prepare-commit, the other not: Proc A Proc B PREPARE phase get neigh_tbl_next_index NONE phase get neigh_tbl_next_index neigh_tbl_next_index++ COMMIT phase neigh_tbl_next_index++ Both A and B got the same index. The fix is to store and increment neigh_tbl_next_index in the PREPARE (or NONE) phase and use value in COMMIT phase: Proc A Proc B PREPARE phase get neigh_tbl_next_index neigh_tbl_next_index++ NONE phase get neigh_tbl_next_index neigh_tbl_next_index++ COMMIT phase // use value stashed in PREPARE phase Reported-by: Simon Horman Signed-off-by: Scott Feldman Reviewed-by: Simon Horman --- drivers/net/ethernet/rocker/rocker.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index c6a6e3c..a9d1559 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -2901,10 +2901,10 @@ static void _rocker_neigh_add(struct rocker *rocker, enum switchdev_trans trans, struct rocker_neigh_tbl_entry *entry) { - entry->index = rocker->neigh_tbl_next_index; + if (trans != SWITCHDEV_TRANS_COMMIT) + entry->index = rocker->neigh_tbl_next_index++; if (trans == SWITCHDEV_TRANS_PREPARE) return; - rocker->neigh_tbl_next_index++; entry->ref_count++; hash_add(rocker->neigh_tbl, &entry->entry, be32_to_cpu(entry->ip_addr));