From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:43983 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751151AbeCGOAU (ORCPT ); Wed, 7 Mar 2018 09:00:20 -0500 From: Paul Blakey To: Thomas Graf , Herbert Xu , David Miller Cc: netdev@vger.kernel.org, Yevgeny Kliteynik , Roi Dayan , Shahar Klein , Mark Bloch , Jiri Pirko , Or Gerlitz , Matan Barak , Paul Blakey Subject: [PATCH net v4 1/2] rhashtable: Fix rhlist duplicates insertion Date: Wed, 7 Mar 2018 16:00:12 +0200 Message-Id: <1520431213-61553-2-git-send-email-paulb@mellanox.com> In-Reply-To: <1520431213-61553-1-git-send-email-paulb@mellanox.com> References: <1520431213-61553-1-git-send-email-paulb@mellanox.com> Sender: netdev-owner@vger.kernel.org List-ID: When inserting duplicate objects (those with the same key), current rhlist implementation messes up the chain pointers by updating the bucket pointer instead of prev next pointer to the newly inserted node. This causes missing elements on removal and travesal. Fix that by properly updating pprev pointer to point to the correct rhash_head next pointer. Fixes: ca26893f05e8 ('rhashtable: Add rhlist interface') Signed-off-by: Paul Blakey --- include/linux/rhashtable.h | 4 +++- lib/rhashtable.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index c9df252..668a21f 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -766,8 +766,10 @@ static inline void *__rhashtable_insert_fast( if (!key || (params.obj_cmpfn ? params.obj_cmpfn(&arg, rht_obj(ht, head)) : - rhashtable_compare(&arg, rht_obj(ht, head)))) + rhashtable_compare(&arg, rht_obj(ht, head)))) { + pprev = &head->next; continue; + } data = rht_obj(ht, head); diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 3825c30..47de025 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -506,8 +506,10 @@ static void *rhashtable_lookup_one(struct rhashtable *ht, if (!key || (ht->p.obj_cmpfn ? ht->p.obj_cmpfn(&arg, rht_obj(ht, head)) : - rhashtable_compare(&arg, rht_obj(ht, head)))) + rhashtable_compare(&arg, rht_obj(ht, head)))) { + pprev = &head->next; continue; + } if (!ht->rhlist) return rht_obj(ht, head); -- 1.8.4.3