From patchwork Wed Dec 16 19:24:44 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucian Adrian Grijincu X-Patchwork-Id: 41285 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 B2D61B6F2B for ; Thu, 17 Dec 2009 06:24:59 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935434AbZLPTYt (ORCPT ); Wed, 16 Dec 2009 14:24:49 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S935440AbZLPTYs (ORCPT ); Wed, 16 Dec 2009 14:24:48 -0500 Received: from ixro-out-rtc.ixiacom.com ([92.87.192.98]:17012 "EHLO ixro-ex1.ixiacom.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S935559AbZLPTYq (ORCPT ); Wed, 16 Dec 2009 14:24:46 -0500 Received: from [10.205.9.89] ([10.205.9.89]) by ixro-ex1.ixiacom.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 16 Dec 2009 21:24:45 +0200 Message-ID: <4B2933FC.7070306@ixiacom.com> Date: Wed, 16 Dec 2009 21:24:44 +0200 From: Lucian Adrian Grijincu User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.6pre) Gecko/20091125 Shredder/3.0.1pre MIME-Version: 1.0 To: netdev@vger.kernel.org CC: Octavian Purdila Subject: [RFC 2/2] udp: udp_lib_get_port start at a different bucket on different processors X-OriginalArrivalTime: 16 Dec 2009 19:24:45.0466 (UTC) FILETIME=[6CCDD7A0:01CA7E85] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On SMP, when ports are not allocated randomly, using the same starting port on all processors will lead to bad performance as all processors will try to get the same hashbucket spinlock: only one will succeed, the rest will spin madly. We solve this problem by making each processor start searching from a different port. To not skip possibly valid port ranges we renormalize the hint value too. Signed-off-by: Lucian Adrian Grijincu --- net/ipv4/udp.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index f437d9d..5d17c71 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -219,7 +219,9 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, first = (((u64)rand * remaining) >> 32) + low; } else { rand = 1; - first = hint; + first = hint + smp_processor_id(); + if (first > high) + first = low + (first - low) % remaining; } /* * force rand to be an odd multiple of UDP_HTABLE_SIZE @@ -243,8 +245,12 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, do { if (low <= snum && snum <= high && !test_bit(snum >> udptable->log, bitmap)) { - if (unlikely(!sysctl_udp_port_randomization)) - hint = snum; + if (unlikely(!sysctl_udp_port_randomization)) { + int cur_hint = snum - smp_processor_id(); + if (cur_hint < low) + cur_hint = high - (low - cur_hint) % remaining; + hint = cur_hint; + } goto found; } snum += rand;