0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/kernel.h>
0034 #include <linux/module.h>
0035 #include <linux/in.h>
0036 #include <linux/ipv6.h>
0037
0038 #include "rds.h"
0039 #include "loop.h"
0040
0041 static char * const rds_trans_modules[] = {
0042 [RDS_TRANS_IB] = "rds_rdma",
0043 [RDS_TRANS_GAP] = NULL,
0044 [RDS_TRANS_TCP] = "rds_tcp",
0045 };
0046
0047 static struct rds_transport *transports[RDS_TRANS_COUNT];
0048 static DECLARE_RWSEM(rds_trans_sem);
0049
0050 void rds_trans_register(struct rds_transport *trans)
0051 {
0052 BUG_ON(strlen(trans->t_name) + 1 > TRANSNAMSIZ);
0053
0054 down_write(&rds_trans_sem);
0055
0056 if (transports[trans->t_type])
0057 printk(KERN_ERR "RDS Transport type %d already registered\n",
0058 trans->t_type);
0059 else {
0060 transports[trans->t_type] = trans;
0061 printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name);
0062 }
0063
0064 up_write(&rds_trans_sem);
0065 }
0066 EXPORT_SYMBOL_GPL(rds_trans_register);
0067
0068 void rds_trans_unregister(struct rds_transport *trans)
0069 {
0070 down_write(&rds_trans_sem);
0071
0072 transports[trans->t_type] = NULL;
0073 printk(KERN_INFO "Unregistered RDS/%s transport\n", trans->t_name);
0074
0075 up_write(&rds_trans_sem);
0076 }
0077 EXPORT_SYMBOL_GPL(rds_trans_unregister);
0078
0079 void rds_trans_put(struct rds_transport *trans)
0080 {
0081 if (trans)
0082 module_put(trans->t_owner);
0083 }
0084
0085 struct rds_transport *rds_trans_get_preferred(struct net *net,
0086 const struct in6_addr *addr,
0087 __u32 scope_id)
0088 {
0089 struct rds_transport *ret = NULL;
0090 struct rds_transport *trans;
0091 unsigned int i;
0092
0093 if (ipv6_addr_v4mapped(addr)) {
0094 if (*(u_int8_t *)&addr->s6_addr32[3] == IN_LOOPBACKNET)
0095 return &rds_loop_transport;
0096 } else if (ipv6_addr_loopback(addr)) {
0097 return &rds_loop_transport;
0098 }
0099
0100 down_read(&rds_trans_sem);
0101 for (i = 0; i < RDS_TRANS_COUNT; i++) {
0102 trans = transports[i];
0103
0104 if (trans && (trans->laddr_check(net, addr, scope_id) == 0) &&
0105 (!trans->t_owner || try_module_get(trans->t_owner))) {
0106 ret = trans;
0107 break;
0108 }
0109 }
0110 up_read(&rds_trans_sem);
0111
0112 return ret;
0113 }
0114
0115 struct rds_transport *rds_trans_get(int t_type)
0116 {
0117 struct rds_transport *ret = NULL;
0118 struct rds_transport *trans;
0119
0120 down_read(&rds_trans_sem);
0121 trans = transports[t_type];
0122 if (!trans) {
0123 up_read(&rds_trans_sem);
0124 if (rds_trans_modules[t_type])
0125 request_module(rds_trans_modules[t_type]);
0126 down_read(&rds_trans_sem);
0127 trans = transports[t_type];
0128 }
0129 if (trans && trans->t_type == t_type &&
0130 (!trans->t_owner || try_module_get(trans->t_owner)))
0131 ret = trans;
0132
0133 up_read(&rds_trans_sem);
0134
0135 return ret;
0136 }
0137
0138
0139
0140
0141
0142
0143
0144 unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter,
0145 unsigned int avail)
0146
0147 {
0148 struct rds_transport *trans;
0149 unsigned int total = 0;
0150 unsigned int part;
0151 int i;
0152
0153 rds_info_iter_unmap(iter);
0154 down_read(&rds_trans_sem);
0155
0156 for (i = 0; i < RDS_TRANS_COUNT; i++) {
0157 trans = transports[i];
0158 if (!trans || !trans->stats_info_copy)
0159 continue;
0160
0161 part = trans->stats_info_copy(iter, avail);
0162 avail -= min(avail, part);
0163 total += part;
0164 }
0165
0166 up_read(&rds_trans_sem);
0167
0168 return total;
0169 }