From patchwork Fri Aug 21 22:28:34 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Grover X-Patchwork-Id: 31850 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 8146AB7B81 for ; Sat, 22 Aug 2009 08:29:10 +1000 (EST) Received: by ozlabs.org (Postfix) id 69350DDD0B; Sat, 22 Aug 2009 08:29:10 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id BC51FDDD01 for ; Sat, 22 Aug 2009 08:29:09 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933128AbZHUW2z (ORCPT ); Fri, 21 Aug 2009 18:28:55 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S933049AbZHUW2y (ORCPT ); Fri, 21 Aug 2009 18:28:54 -0400 Received: from acsinet12.oracle.com ([141.146.126.234]:59348 "EHLO acsinet12.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755488AbZHUW2v (ORCPT ); Fri, 21 Aug 2009 18:28:51 -0400 Received: from rgminet15.oracle.com (rcsinet15.oracle.com [148.87.113.117]) by acsinet12.oracle.com (Switch-3.3.1/Switch-3.3.1) with ESMTP id n7LMSIKZ015445 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 21 Aug 2009 22:28:20 GMT Received: from abhmt009.oracle.com (abhmt009.oracle.com [141.146.116.18]) by rgminet15.oracle.com (Switch-3.3.1/Switch-3.3.1) with ESMTP id n7LMSm2S031618; Fri, 21 Aug 2009 22:28:48 GMT Received: from localhost.localdomain (/139.185.48.5) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 21 Aug 2009 15:28:47 -0700 From: Andy Grover To: netdev@vger.kernel.org Cc: rds-devel@oss.oracle.com Subject: [PATCH 4/5] RDS: Track transports via an array, not a list Date: Fri, 21 Aug 2009 15:28:34 -0700 Message-Id: <1250893715-21939-5-git-send-email-andy.grover@oracle.com> X-Mailer: git-send-email 1.6.0.4 In-Reply-To: <1250893715-21939-1-git-send-email-andy.grover@oracle.com> References: <1250893715-21939-1-git-send-email-andy.grover@oracle.com> X-Source-IP: abhmt009.oracle.com [141.146.116.18] X-Auth-Type: Internal IP X-CT-RefId: str=0001.0A090205.4A8F1FA0.00FA:SCFSTAT5015188,ss=1,fgs=0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Now that transports can be loaded in arbitrary order, it is important for rds_trans_get_preferred() to look for them in a particular order, instead of walking the list until it finds a transport that works for a given address. Now, each transport registers for a specific transport slot, and these are ordered so that preferred transports come first, and then if they are not loaded, other transports are queried. Signed-off-by: Andy Grover --- net/rds/ib.c | 1 + net/rds/iw.c | 1 + net/rds/rds.h | 6 ++++++ net/rds/tcp.c | 1 + net/rds/transport.c | 29 +++++++++++++++++++---------- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 868559a..536ebe5 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -282,6 +282,7 @@ struct rds_transport rds_ib_transport = { .flush_mrs = rds_ib_flush_mrs, .t_owner = THIS_MODULE, .t_name = "infiniband", + .t_type = RDS_TRANS_IB }; int __init rds_ib_init(void) diff --git a/net/rds/iw.c b/net/rds/iw.c index f5e9a29..db224f7 100644 --- a/net/rds/iw.c +++ b/net/rds/iw.c @@ -284,6 +284,7 @@ struct rds_transport rds_iw_transport = { .flush_mrs = rds_iw_flush_mrs, .t_owner = THIS_MODULE, .t_name = "iwarp", + .t_type = RDS_TRANS_IWARP, .t_prefer_loopback = 1, }; diff --git a/net/rds/rds.h b/net/rds/rds.h index 290566c..85d6f89 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -311,11 +311,17 @@ struct rds_notifier { * flag and header. */ +#define RDS_TRANS_IB 0 +#define RDS_TRANS_IWARP 1 +#define RDS_TRANS_TCP 2 +#define RDS_TRANS_COUNT 3 + struct rds_transport { char t_name[TRANSNAMSIZ]; struct list_head t_item; struct module *t_owner; unsigned int t_prefer_loopback:1; + unsigned int t_type; int (*laddr_check)(__be32 addr); int (*conn_alloc)(struct rds_connection *conn, gfp_t gfp); diff --git a/net/rds/tcp.c b/net/rds/tcp.c index e0ac900..b5198ae 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -271,6 +271,7 @@ struct rds_transport rds_tcp_transport = { .exit = rds_tcp_exit, .t_owner = THIS_MODULE, .t_name = "tcp", + .t_type = RDS_TRANS_TCP, .t_prefer_loopback = 1, }; diff --git a/net/rds/transport.c b/net/rds/transport.c index 56a5309..7e10679 100644 --- a/net/rds/transport.c +++ b/net/rds/transport.c @@ -37,7 +37,7 @@ #include "rds.h" #include "loop.h" -static LIST_HEAD(rds_transports); +static struct rds_transport *transports[RDS_TRANS_COUNT]; static DECLARE_RWSEM(rds_trans_sem); int rds_trans_register(struct rds_transport *trans) @@ -46,8 +46,13 @@ int rds_trans_register(struct rds_transport *trans) down_write(&rds_trans_sem); - list_add_tail(&trans->t_item, &rds_transports); - printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name); + if (transports[trans->t_type]) + printk(KERN_ERR "RDS Transport type %d already registered\n", + trans->t_type); + else { + transports[trans->t_type] = trans; + printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name); + } up_write(&rds_trans_sem); @@ -59,7 +64,7 @@ void rds_trans_unregister(struct rds_transport *trans) { down_write(&rds_trans_sem); - list_del_init(&trans->t_item); + transports[trans->t_type] = NULL; printk(KERN_INFO "Unregistered RDS/%s transport\n", trans->t_name); up_write(&rds_trans_sem); @@ -68,16 +73,17 @@ EXPORT_SYMBOL_GPL(rds_trans_unregister); struct rds_transport *rds_trans_get_preferred(__be32 addr) { - struct rds_transport *trans; struct rds_transport *ret = NULL; + int i; if (IN_LOOPBACK(ntohl(addr))) return &rds_loop_transport; down_read(&rds_trans_sem); - list_for_each_entry(trans, &rds_transports, t_item) { - if (trans->laddr_check(addr) == 0) { - ret = trans; + for (i = 0; i < RDS_TRANS_COUNT; i++) + { + if (transports[i] && (transports[i]->laddr_check(addr) == 0)) { + ret = transports[i]; break; } } @@ -99,12 +105,15 @@ unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter, struct rds_transport *trans; unsigned int total = 0; unsigned int part; + int i; rds_info_iter_unmap(iter); down_read(&rds_trans_sem); - list_for_each_entry(trans, &rds_transports, t_item) { - if (trans->stats_info_copy == NULL) + for (i = 0; i < RDS_TRANS_COUNT; i++) + { + trans = transports[i]; + if (!trans || !trans->stats_info_copy) continue; part = trans->stats_info_copy(iter, avail);