33 #include <linux/kernel.h>
34 #include <linux/list.h>
35 #include <linux/slab.h>
36 #include <linux/export.h>
42 #define RDS_CONNECTION_HASH_BITS 12
43 #define RDS_CONNECTION_HASH_ENTRIES (1 << RDS_CONNECTION_HASH_BITS)
44 #define RDS_CONNECTION_HASH_MASK (RDS_CONNECTION_HASH_ENTRIES - 1)
48 static unsigned long rds_conn_count;
55 unsigned long hash = inet_ehashfn(
NULL,
61 #define rds_conn_info_set(var, test, suffix) do { \
63 var |= RDS_INFO_CONNECTION_FLAG_##suffix; \
74 hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) {
81 rdsdebug(
"returning conn %p for %pI4 -> %pI4\n", ret,
94 rdsdebug(
"connection %pI4 to %pI4 reset\n",
126 conn = rds_conn_lookup(head, laddr, faddr, trans);
140 conn = kmem_cache_zalloc(rds_conn_slab, gfp);
199 rdsdebug(
"allocated conn %p for %pI4 -> %pI4 over %s %s\n",
200 conn, &laddr, &faddr,
202 is_outgoing ?
"(outgoing)" :
"");
227 found = rds_conn_lookup(head, laddr, faddr, trans);
238 spin_unlock_irqrestore(&rds_conn_lock, flags);
247 return __rds_conn_create(laddr, faddr, trans, gfp, 0);
254 return __rds_conn_create(laddr, faddr, trans, gfp, 1);
282 conn->
c_trans->conn_shutdown(conn);
283 rds_conn_reset(conn);
292 "%s: failed to transition to state DOWN, "
293 "current state is %d\n",
326 rdsdebug(
"freeing conn %p for %pI4 -> "
327 "%pI4\n", conn, &conn->
c_laddr,
331 spin_lock_irq(&rds_conn_lock);
333 spin_unlock_irq(&rds_conn_lock);
369 spin_unlock_irqrestore(&rds_conn_lock, flags);
373 static void rds_conn_message_info(
struct socket *
sock,
unsigned int len,
383 unsigned int total = 0;
391 for (i = 0, head = rds_conn_hash; i <
ARRAY_SIZE(rds_conn_hash);
393 hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) {
410 spin_unlock_irqrestore(&conn->
c_lock, flags);
419 static void rds_conn_message_info_send(
struct socket *sock,
unsigned int len,
423 rds_conn_message_info(sock, len, iter, lens, 1);
426 static void rds_conn_message_info_retrans(
struct socket *sock,
431 rds_conn_message_info(sock, len, iter, lens, 0);
449 lens->
each = item_len;
451 for (i = 0, head = rds_conn_hash; i <
ARRAY_SIZE(rds_conn_hash);
453 hlist_for_each_entry_rcu(conn, pos, head,
c_hash_node) {
456 if (!visitor(conn,
buffer))
462 if (len >= item_len) {
498 static void rds_conn_info(
struct socket *sock,
unsigned int len,
503 rds_conn_info_visitor,
517 rds_conn_message_info_send);
519 rds_conn_message_info_retrans);
528 WARN_ON(!hlist_empty(rds_conn_hash));
534 rds_conn_message_info_send);
536 rds_conn_message_info_retrans);