From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 69379A0524; Sun, 11 Apr 2021 20:51:14 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id DA5D61413EF; Sun, 11 Apr 2021 20:51:13 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id 4E2F71413EA for ; Sun, 11 Apr 2021 20:51:11 +0200 (CEST) IronPort-SDR: tiRSQb+z4Z8dA55HUb6snDD3xtYiqIOvD0S+uA6TlEk+agJDHGvUQVxwgF6fzRJ7tU+xZuOr+2 aHlLZiiwkyEQ== X-IronPort-AV: E=McAfee;i="6000,8403,9951"; a="194172739" X-IronPort-AV: E=Sophos;i="5.82,214,1613462400"; d="scan'208";a="194172739" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Apr 2021 11:51:10 -0700 IronPort-SDR: R872mS+rj1M6RIcTT1Ynh1hv14hvGx+5WmV9mTbZKdiZq3qGNYEN2jLVb4BxpLfiYfDyq9vbs+ HAUdScAwajtg== X-IronPort-AV: E=Sophos;i="5.82,214,1613462400"; d="scan'208";a="398117459" Received: from vmedvedk-mobl.ger.corp.intel.com (HELO [10.252.4.10]) ([10.252.4.10]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Apr 2021 11:51:08 -0700 To: "Ananyev, Konstantin" , "dev@dpdk.org" Cc: "Chilikin, Andrey" , "Kinsella, Ray" , "Wang, Yipeng1" , "Gobriel, Sameh" , "Richardson, Bruce" References: <1615919077-77774-1-git-send-email-vladimir.medvedkin@intel.com> <1617738643-258635-3-git-send-email-vladimir.medvedkin@intel.com> From: "Medvedkin, Vladimir" Message-ID: <3fb31ad3-cb84-05a4-fb0e-46e33e008f57@intel.com> Date: Sun, 11 Apr 2021 21:51:05 +0300 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Subject: Re: [dpdk-dev] [PATCH v2 2/3] hash: add predictable RSS implementation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi Konstantin, Thanks for the review, On 07/04/2021 15:53, Ananyev, Konstantin wrote: > Hi Vladimir, > > Few comments below, mostly minor. > One generic one - doc seems missing. > With that in place: > Acked-by: Konstantin Ananyev > >> >> This patch implements predictable RSS functionality. >> >> Signed-off-by: Vladimir Medvedkin >> +#defineRETA_SZ_MIN2U >> +#defineRETA_SZ_MAX16U > > Should these RETA_SZ defines be in public header? > So user can know what are allowed values? > I don't think this is necessary, because the user chooses it not arbitrary, but depending on the NIC. >> +#define RETA_SZ_IN_RANGE(reta_sz)((reta_sz >= RETA_SZ_MIN) && \ >> +uint32_t i; > > Empty line is missing. > Thanks >> +if ((name == NULL) || (key_len == 0) || !RETA_SZ_IN_RANGE(reta_sz)) { >> +rte_errno = EINVAL; >> +return NULL; >> +} >> +static inline void >> +set_bit(uint8_t *ptr, uint32_t bit, uint32_t pos) >> +{ >> +uint32_t byte_idx = pos >> 3; > > Just as a nit to be consistent with the line below: > pos / CHAR_BIT; > Fixed >> +uint32_t bit_idx = (CHAR_BIT - 1) - (pos & (CHAR_BIT - 1)); >> +uint8_t tmp; >> +ent = rte_zmalloc(NULL, sizeof(struct rte_thash_subtuple_helper) + >> +sizeof(uint32_t) * (1 << ctx->reta_sz_log), 0); > > Helper can be used by data-path code (via rte_thash_get_compliment()) right? > Then might be better to align it at cache-line. > Agree, I'll fix it >> +if (ent == NULL) >> +return -ENOMEM; >> uint32_t >> -rte_thash_get_compliment(struct rte_thash_subtuple_helper *h __rte_unused, >> -uint32_t hash __rte_unused, uint32_t desired_hash __rte_unused) >> +rte_thash_get_compliment(struct rte_thash_subtuple_helper *h, >> +uint32_t hash, uint32_t desired_hash) >> { >> -return 0; >> +return h->compl_table[(hash ^ desired_hash) & h->lsb_msk]; >> } > > Would it make sense to add another-one for multi values: > rte_thash_get_compliment(uint32_t hash, const uint32_t desired_hashes[], uint32_t adj_hash[], uint32_t num); > So user can get adjustment values for multiple queues at once? > At the moment I can't find scenarios why do we need to have a bulk version for this function >> >> const uint8_t * >> -rte_thash_get_key(struct rte_thash_ctx *ctx __rte_unused) >> +rte_thash_get_key(struct rte_thash_ctx *ctx) >> { >> -return NULL; >> +return ctx->hash_key; >> +} >> + >> +static inline void >> +xor_bit(uint8_t *ptr, uint32_t bit, uint32_t pos) >> +{ >> +uint32_t byte_idx = pos >> 3; >> +uint32_t bit_idx = (CHAR_BIT - 1) - (pos & (CHAR_BIT - 1)); >> +uint8_t tmp; >> + >> +tmp = ptr[byte_idx]; >> +tmp ^= bit << bit_idx; >> +ptr[byte_idx] = tmp; >> +} >> + >> +int >> +rte_thash_adjust_tuple(struct rte_thash_subtuple_helper *h, >> +uint8_t *orig_tuple, uint32_t adj_bits, >> +rte_thash_check_tuple_t fn, void *userdata) >> +{ >> +unsigned i; >> + >> +if ((h == NULL) || (orig_tuple == NULL)) >> +return -EINVAL; >> + >> +adj_bits &= h->lsb_msk; >> +/* Hint: LSB of adj_bits corresponds to offset + len bit of tuple */ >> +for (i = 0; i < sizeof(uint32_t) * CHAR_BIT; i++) { >> +uint8_t bit = (adj_bits >> i) & 0x1; >> +if (bit) >> +xor_bit(orig_tuple, bit, >> +h->tuple_offset + h->tuple_len - 1 - i); >> +} >> + >> +if (fn != NULL) >> +return (fn(userdata, orig_tuple)) ? 0 : -EEXIST; >> + >> +return 0; >> } > > Not sure is there much point to have a callback that is called only once. > Might be better to rework the function in a way that user to provide 2 callbacks - > one to generate new value, second to check. > Something like that: > > int > rte_thash_gen_tuple(struct rte_thash_subtuple_helper *h, > uint8_t *tuple, uint32_t desired_hash, > int (*cb_gen_tuple)(uint8_t *, void *), > int (*cb_check_tuple)(const uint8_t *, void *), > void *userdata) > { > do { > rc = cb_gen_tuple(tuple, userdata); > if (rc != 0) > return rc; > hash = rte_softrss(tuple, ...); > adj = rte_thash_get_compliment(h, hash, desired_hash); > update_tuple(tuple, adj, ...); > rc = cb_check_tuple(tuple, userdata); > } while(rc != 0); > > return rc; > } Agree, there is no point to call the callback for a single function call. I'll rewrite rte_thash_adjust_tuple() and send a new version an v3. As for gen_tuple, I think we don't need to have a separate callback, new rte_thash_adjust_tuple implementation randomly changes corresponding bits (based on configured offset and length in the helper) in the tuple. > >> diff --git a/lib/librte_hash/rte_thash.h b/lib/librte_hash/rte_thash.h >> index 38a641b..fd67931 100644 >> --- a/lib/librte_hash/rte_thash.h >> +++ b/lib/librte_hash/rte_thash.h >> @@ -360,6 +360,48 @@ __rte_experimental >> const uint8_t * >> rte_thash_get_key(struct rte_thash_ctx *ctx); >> >> +/** >> + * Function prototype for the rte_thash_adjust_tuple >> + * to check if adjusted tuple could be used. >> + * Generally it is some kind of lookup function to check >> + * if adjusted tuple is already in use. >> + * >> + * @param userdata >> + * Pointer to the userdata. It could be a pointer to the >> + * table with used tuples to search. >> + * @param tuple >> + * Pointer to the tuple to check >> + * >> + * @return >> + * 1 on success >> + * 0 otherwise >> + */ >> +typedef int (*rte_thash_check_tuple_t)(void *userdata, uint8_t *tuple); >> + >> +/** >> + * Adjust tuple with complimentary bits. >> + * >> + * @param h >> + * Pointer to the helper struct >> + * @param orig_tuple >> + * Pointer to the tuple to be adjusted >> + * @param adj_bits >> + * Valure returned by rte_thash_get_compliment >> + * @param fn >> + * Callback function to check adjusted tuple. Could be NULL >> + * @param userdata >> + * Pointer to the userdata to be passed to fn(). Could be NULL >> + * >> + * @return >> + * 0 on success >> + * negative otherwise >> + */ >> +__rte_experimental >> +int >> +rte_thash_adjust_tuple(struct rte_thash_subtuple_helper *h, >> +uint8_t *orig_tuple, uint32_t adj_bits, >> +rte_thash_check_tuple_t fn, void *userdata); >> + >> #ifdef __cplusplus >> } >> #endif >> diff --git a/lib/librte_hash/version.map b/lib/librte_hash/version.map >> index 93cb230..a992a1e 100644 >> --- a/lib/librte_hash/version.map >> +++ b/lib/librte_hash/version.map >> @@ -32,6 +32,7 @@ DPDK_21 { >> EXPERIMENTAL { >> global: >> >> +rte_thash_adjust_tuple; >> rte_hash_free_key_with_position; >> rte_hash_lookup_with_hash_bulk; >> rte_hash_lookup_with_hash_bulk_data; >> -- >> 2.7.4 > -- Regards, Vladimir