diff options
-rw-r--r-- | include/uapi/linux/rds.h | 69 | ||||
-rw-r--r-- | net/rds/connection.c | 101 | ||||
-rw-r--r-- | net/rds/ib.c | 52 | ||||
-rw-r--r-- | net/rds/ib_mr.h | 2 | ||||
-rw-r--r-- | net/rds/ib_rdma.c | 11 | ||||
-rw-r--r-- | net/rds/recv.c | 25 | ||||
-rw-r--r-- | net/rds/tcp.c | 44 |
7 files changed, 293 insertions, 11 deletions
diff --git a/include/uapi/linux/rds.h b/include/uapi/linux/rds.h index 20c6bd0b0007..dc520e1a4123 100644 --- a/include/uapi/linux/rds.h +++ b/include/uapi/linux/rds.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2008 Oracle. All rights reserved. | 3 | * Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved. |
4 | * | 4 | * |
5 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
6 | * licenses. You may choose to be licensed under the terms of the GNU | 6 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -118,7 +118,17 @@ | |||
118 | #define RDS_INFO_IB_CONNECTIONS 10008 | 118 | #define RDS_INFO_IB_CONNECTIONS 10008 |
119 | #define RDS_INFO_CONNECTION_STATS 10009 | 119 | #define RDS_INFO_CONNECTION_STATS 10009 |
120 | #define RDS_INFO_IWARP_CONNECTIONS 10010 | 120 | #define RDS_INFO_IWARP_CONNECTIONS 10010 |
121 | #define RDS_INFO_LAST 10010 | 121 | |
122 | /* PF_RDS6 options */ | ||
123 | #define RDS6_INFO_CONNECTIONS 10011 | ||
124 | #define RDS6_INFO_SEND_MESSAGES 10012 | ||
125 | #define RDS6_INFO_RETRANS_MESSAGES 10013 | ||
126 | #define RDS6_INFO_RECV_MESSAGES 10014 | ||
127 | #define RDS6_INFO_SOCKETS 10015 | ||
128 | #define RDS6_INFO_TCP_SOCKETS 10016 | ||
129 | #define RDS6_INFO_IB_CONNECTIONS 10017 | ||
130 | |||
131 | #define RDS_INFO_LAST 10017 | ||
122 | 132 | ||
123 | struct rds_info_counter { | 133 | struct rds_info_counter { |
124 | __u8 name[32]; | 134 | __u8 name[32]; |
@@ -140,6 +150,15 @@ struct rds_info_connection { | |||
140 | __u8 flags; | 150 | __u8 flags; |
141 | } __attribute__((packed)); | 151 | } __attribute__((packed)); |
142 | 152 | ||
153 | struct rds6_info_connection { | ||
154 | __u64 next_tx_seq; | ||
155 | __u64 next_rx_seq; | ||
156 | struct in6_addr laddr; | ||
157 | struct in6_addr faddr; | ||
158 | __u8 transport[TRANSNAMSIZ]; /* null term ascii */ | ||
159 | __u8 flags; | ||
160 | } __attribute__((packed)); | ||
161 | |||
143 | #define RDS_INFO_MESSAGE_FLAG_ACK 0x01 | 162 | #define RDS_INFO_MESSAGE_FLAG_ACK 0x01 |
144 | #define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02 | 163 | #define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02 |
145 | 164 | ||
@@ -153,6 +172,17 @@ struct rds_info_message { | |||
153 | __u8 flags; | 172 | __u8 flags; |
154 | } __attribute__((packed)); | 173 | } __attribute__((packed)); |
155 | 174 | ||
175 | struct rds6_info_message { | ||
176 | __u64 seq; | ||
177 | __u32 len; | ||
178 | struct in6_addr laddr; | ||
179 | struct in6_addr faddr; | ||
180 | __be16 lport; | ||
181 | __be16 fport; | ||
182 | __u8 flags; | ||
183 | __u8 tos; | ||
184 | } __attribute__((packed)); | ||
185 | |||
156 | struct rds_info_socket { | 186 | struct rds_info_socket { |
157 | __u32 sndbuf; | 187 | __u32 sndbuf; |
158 | __be32 bound_addr; | 188 | __be32 bound_addr; |
@@ -163,6 +193,16 @@ struct rds_info_socket { | |||
163 | __u64 inum; | 193 | __u64 inum; |
164 | } __attribute__((packed)); | 194 | } __attribute__((packed)); |
165 | 195 | ||
196 | struct rds6_info_socket { | ||
197 | __u32 sndbuf; | ||
198 | struct in6_addr bound_addr; | ||
199 | struct in6_addr connected_addr; | ||
200 | __be16 bound_port; | ||
201 | __be16 connected_port; | ||
202 | __u32 rcvbuf; | ||
203 | __u64 inum; | ||
204 | } __attribute__((packed)); | ||
205 | |||
166 | struct rds_info_tcp_socket { | 206 | struct rds_info_tcp_socket { |
167 | __be32 local_addr; | 207 | __be32 local_addr; |
168 | __be16 local_port; | 208 | __be16 local_port; |
@@ -175,6 +215,18 @@ struct rds_info_tcp_socket { | |||
175 | __u32 last_seen_una; | 215 | __u32 last_seen_una; |
176 | } __attribute__((packed)); | 216 | } __attribute__((packed)); |
177 | 217 | ||
218 | struct rds6_info_tcp_socket { | ||
219 | struct in6_addr local_addr; | ||
220 | __be16 local_port; | ||
221 | struct in6_addr peer_addr; | ||
222 | __be16 peer_port; | ||
223 | __u64 hdr_rem; | ||
224 | __u64 data_rem; | ||
225 | __u32 last_sent_nxt; | ||
226 | __u32 last_expected_una; | ||
227 | __u32 last_seen_una; | ||
228 | } __attribute__((packed)); | ||
229 | |||
178 | #define RDS_IB_GID_LEN 16 | 230 | #define RDS_IB_GID_LEN 16 |
179 | struct rds_info_rdma_connection { | 231 | struct rds_info_rdma_connection { |
180 | __be32 src_addr; | 232 | __be32 src_addr; |
@@ -189,6 +241,19 @@ struct rds_info_rdma_connection { | |||
189 | __u32 rdma_mr_size; | 241 | __u32 rdma_mr_size; |
190 | }; | 242 | }; |
191 | 243 | ||
244 | struct rds6_info_rdma_connection { | ||
245 | struct in6_addr src_addr; | ||
246 | struct in6_addr dst_addr; | ||
247 | __u8 src_gid[RDS_IB_GID_LEN]; | ||
248 | __u8 dst_gid[RDS_IB_GID_LEN]; | ||
249 | |||
250 | __u32 max_send_wr; | ||
251 | __u32 max_recv_wr; | ||
252 | __u32 max_send_sge; | ||
253 | __u32 rdma_mr_max; | ||
254 | __u32 rdma_mr_size; | ||
255 | }; | ||
256 | |||
192 | /* RDS message Receive Path Latency points */ | 257 | /* RDS message Receive Path Latency points */ |
193 | enum rds_message_rxpath_latency { | 258 | enum rds_message_rxpath_latency { |
194 | RDS_MSG_RX_HDR_TO_DGRAM_START = 0, | 259 | RDS_MSG_RX_HDR_TO_DGRAM_START = 0, |
diff --git a/net/rds/connection.c b/net/rds/connection.c index 5c9ceed55dae..051e35c1e7c6 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c | |||
@@ -498,16 +498,19 @@ EXPORT_SYMBOL_GPL(rds_conn_destroy); | |||
498 | 498 | ||
499 | static void __rds_inc_msg_cp(struct rds_incoming *inc, | 499 | static void __rds_inc_msg_cp(struct rds_incoming *inc, |
500 | struct rds_info_iterator *iter, | 500 | struct rds_info_iterator *iter, |
501 | void *saddr, void *daddr, int flip) | 501 | void *saddr, void *daddr, int flip, bool isv6) |
502 | { | 502 | { |
503 | rds_inc_info_copy(inc, iter, *(__be32 *)saddr, | 503 | if (isv6) |
504 | *(__be32 *)daddr, flip); | 504 | rds6_inc_info_copy(inc, iter, saddr, daddr, flip); |
505 | else | ||
506 | rds_inc_info_copy(inc, iter, *(__be32 *)saddr, | ||
507 | *(__be32 *)daddr, flip); | ||
505 | } | 508 | } |
506 | 509 | ||
507 | static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len, | 510 | static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len, |
508 | struct rds_info_iterator *iter, | 511 | struct rds_info_iterator *iter, |
509 | struct rds_info_lengths *lens, | 512 | struct rds_info_lengths *lens, |
510 | int want_send) | 513 | int want_send, bool isv6) |
511 | { | 514 | { |
512 | struct hlist_head *head; | 515 | struct hlist_head *head; |
513 | struct list_head *list; | 516 | struct list_head *list; |
@@ -518,7 +521,10 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len, | |||
518 | size_t i; | 521 | size_t i; |
519 | int j; | 522 | int j; |
520 | 523 | ||
521 | len /= sizeof(struct rds_info_message); | 524 | if (isv6) |
525 | len /= sizeof(struct rds6_info_message); | ||
526 | else | ||
527 | len /= sizeof(struct rds_info_message); | ||
522 | 528 | ||
523 | rcu_read_lock(); | 529 | rcu_read_lock(); |
524 | 530 | ||
@@ -528,6 +534,9 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len, | |||
528 | struct rds_conn_path *cp; | 534 | struct rds_conn_path *cp; |
529 | int npaths; | 535 | int npaths; |
530 | 536 | ||
537 | if (!isv6 && conn->c_isv6) | ||
538 | continue; | ||
539 | |||
531 | npaths = (conn->c_trans->t_mp_capable ? | 540 | npaths = (conn->c_trans->t_mp_capable ? |
532 | RDS_MPATH_WORKERS : 1); | 541 | RDS_MPATH_WORKERS : 1); |
533 | 542 | ||
@@ -548,7 +557,7 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len, | |||
548 | iter, | 557 | iter, |
549 | &conn->c_laddr, | 558 | &conn->c_laddr, |
550 | &conn->c_faddr, | 559 | &conn->c_faddr, |
551 | 0); | 560 | 0, isv6); |
552 | } | 561 | } |
553 | 562 | ||
554 | spin_unlock_irqrestore(&cp->cp_lock, flags); | 563 | spin_unlock_irqrestore(&cp->cp_lock, flags); |
@@ -558,7 +567,10 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len, | |||
558 | rcu_read_unlock(); | 567 | rcu_read_unlock(); |
559 | 568 | ||
560 | lens->nr = total; | 569 | lens->nr = total; |
561 | lens->each = sizeof(struct rds_info_message); | 570 | if (isv6) |
571 | lens->each = sizeof(struct rds6_info_message); | ||
572 | else | ||
573 | lens->each = sizeof(struct rds_info_message); | ||
562 | } | 574 | } |
563 | 575 | ||
564 | static void rds_conn_message_info(struct socket *sock, unsigned int len, | 576 | static void rds_conn_message_info(struct socket *sock, unsigned int len, |
@@ -566,7 +578,15 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, | |||
566 | struct rds_info_lengths *lens, | 578 | struct rds_info_lengths *lens, |
567 | int want_send) | 579 | int want_send) |
568 | { | 580 | { |
569 | rds_conn_message_info_cmn(sock, len, iter, lens, want_send); | 581 | rds_conn_message_info_cmn(sock, len, iter, lens, want_send, false); |
582 | } | ||
583 | |||
584 | static void rds6_conn_message_info(struct socket *sock, unsigned int len, | ||
585 | struct rds_info_iterator *iter, | ||
586 | struct rds_info_lengths *lens, | ||
587 | int want_send) | ||
588 | { | ||
589 | rds_conn_message_info_cmn(sock, len, iter, lens, want_send, true); | ||
570 | } | 590 | } |
571 | 591 | ||
572 | static void rds_conn_message_info_send(struct socket *sock, unsigned int len, | 592 | static void rds_conn_message_info_send(struct socket *sock, unsigned int len, |
@@ -576,6 +596,13 @@ static void rds_conn_message_info_send(struct socket *sock, unsigned int len, | |||
576 | rds_conn_message_info(sock, len, iter, lens, 1); | 596 | rds_conn_message_info(sock, len, iter, lens, 1); |
577 | } | 597 | } |
578 | 598 | ||
599 | static void rds6_conn_message_info_send(struct socket *sock, unsigned int len, | ||
600 | struct rds_info_iterator *iter, | ||
601 | struct rds_info_lengths *lens) | ||
602 | { | ||
603 | rds6_conn_message_info(sock, len, iter, lens, 1); | ||
604 | } | ||
605 | |||
579 | static void rds_conn_message_info_retrans(struct socket *sock, | 606 | static void rds_conn_message_info_retrans(struct socket *sock, |
580 | unsigned int len, | 607 | unsigned int len, |
581 | struct rds_info_iterator *iter, | 608 | struct rds_info_iterator *iter, |
@@ -584,6 +611,14 @@ static void rds_conn_message_info_retrans(struct socket *sock, | |||
584 | rds_conn_message_info(sock, len, iter, lens, 0); | 611 | rds_conn_message_info(sock, len, iter, lens, 0); |
585 | } | 612 | } |
586 | 613 | ||
614 | static void rds6_conn_message_info_retrans(struct socket *sock, | ||
615 | unsigned int len, | ||
616 | struct rds_info_iterator *iter, | ||
617 | struct rds_info_lengths *lens) | ||
618 | { | ||
619 | rds6_conn_message_info(sock, len, iter, lens, 0); | ||
620 | } | ||
621 | |||
587 | void rds_for_each_conn_info(struct socket *sock, unsigned int len, | 622 | void rds_for_each_conn_info(struct socket *sock, unsigned int len, |
588 | struct rds_info_iterator *iter, | 623 | struct rds_info_iterator *iter, |
589 | struct rds_info_lengths *lens, | 624 | struct rds_info_lengths *lens, |
@@ -699,6 +734,34 @@ static int rds_conn_info_visitor(struct rds_conn_path *cp, void *buffer) | |||
699 | return 1; | 734 | return 1; |
700 | } | 735 | } |
701 | 736 | ||
737 | static int rds6_conn_info_visitor(struct rds_conn_path *cp, void *buffer) | ||
738 | { | ||
739 | struct rds6_info_connection *cinfo6 = buffer; | ||
740 | struct rds_connection *conn = cp->cp_conn; | ||
741 | |||
742 | cinfo6->next_tx_seq = cp->cp_next_tx_seq; | ||
743 | cinfo6->next_rx_seq = cp->cp_next_rx_seq; | ||
744 | cinfo6->laddr = conn->c_laddr; | ||
745 | cinfo6->faddr = conn->c_faddr; | ||
746 | strncpy(cinfo6->transport, conn->c_trans->t_name, | ||
747 | sizeof(cinfo6->transport)); | ||
748 | cinfo6->flags = 0; | ||
749 | |||
750 | rds_conn_info_set(cinfo6->flags, test_bit(RDS_IN_XMIT, &cp->cp_flags), | ||
751 | SENDING); | ||
752 | /* XXX Future: return the state rather than these funky bits */ | ||
753 | rds_conn_info_set(cinfo6->flags, | ||
754 | atomic_read(&cp->cp_state) == RDS_CONN_CONNECTING, | ||
755 | CONNECTING); | ||
756 | rds_conn_info_set(cinfo6->flags, | ||
757 | atomic_read(&cp->cp_state) == RDS_CONN_UP, | ||
758 | CONNECTED); | ||
759 | /* Just return 1 as there is no error case. This is a helper function | ||
760 | * for rds_walk_conn_path_info() and it wants a return value. | ||
761 | */ | ||
762 | return 1; | ||
763 | } | ||
764 | |||
702 | static void rds_conn_info(struct socket *sock, unsigned int len, | 765 | static void rds_conn_info(struct socket *sock, unsigned int len, |
703 | struct rds_info_iterator *iter, | 766 | struct rds_info_iterator *iter, |
704 | struct rds_info_lengths *lens) | 767 | struct rds_info_lengths *lens) |
@@ -711,6 +774,18 @@ static void rds_conn_info(struct socket *sock, unsigned int len, | |||
711 | sizeof(struct rds_info_connection)); | 774 | sizeof(struct rds_info_connection)); |
712 | } | 775 | } |
713 | 776 | ||
777 | static void rds6_conn_info(struct socket *sock, unsigned int len, | ||
778 | struct rds_info_iterator *iter, | ||
779 | struct rds_info_lengths *lens) | ||
780 | { | ||
781 | u64 buffer[(sizeof(struct rds6_info_connection) + 7) / 8]; | ||
782 | |||
783 | rds_walk_conn_path_info(sock, len, iter, lens, | ||
784 | rds6_conn_info_visitor, | ||
785 | buffer, | ||
786 | sizeof(struct rds6_info_connection)); | ||
787 | } | ||
788 | |||
714 | int rds_conn_init(void) | 789 | int rds_conn_init(void) |
715 | { | 790 | { |
716 | int ret; | 791 | int ret; |
@@ -732,6 +807,11 @@ int rds_conn_init(void) | |||
732 | rds_conn_message_info_send); | 807 | rds_conn_message_info_send); |
733 | rds_info_register_func(RDS_INFO_RETRANS_MESSAGES, | 808 | rds_info_register_func(RDS_INFO_RETRANS_MESSAGES, |
734 | rds_conn_message_info_retrans); | 809 | rds_conn_message_info_retrans); |
810 | rds_info_register_func(RDS6_INFO_CONNECTIONS, rds6_conn_info); | ||
811 | rds_info_register_func(RDS6_INFO_SEND_MESSAGES, | ||
812 | rds6_conn_message_info_send); | ||
813 | rds_info_register_func(RDS6_INFO_RETRANS_MESSAGES, | ||
814 | rds6_conn_message_info_retrans); | ||
735 | 815 | ||
736 | return 0; | 816 | return 0; |
737 | } | 817 | } |
@@ -750,6 +830,11 @@ void rds_conn_exit(void) | |||
750 | rds_conn_message_info_send); | 830 | rds_conn_message_info_send); |
751 | rds_info_deregister_func(RDS_INFO_RETRANS_MESSAGES, | 831 | rds_info_deregister_func(RDS_INFO_RETRANS_MESSAGES, |
752 | rds_conn_message_info_retrans); | 832 | rds_conn_message_info_retrans); |
833 | rds_info_deregister_func(RDS6_INFO_CONNECTIONS, rds6_conn_info); | ||
834 | rds_info_deregister_func(RDS6_INFO_SEND_MESSAGES, | ||
835 | rds6_conn_message_info_send); | ||
836 | rds_info_deregister_func(RDS6_INFO_RETRANS_MESSAGES, | ||
837 | rds6_conn_message_info_retrans); | ||
753 | } | 838 | } |
754 | 839 | ||
755 | /* | 840 | /* |
diff --git a/net/rds/ib.c b/net/rds/ib.c index 756225c5540f..63d95ea7cdff 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c | |||
@@ -321,6 +321,43 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn, | |||
321 | return 1; | 321 | return 1; |
322 | } | 322 | } |
323 | 323 | ||
324 | /* IPv6 version of rds_ib_conn_info_visitor(). */ | ||
325 | static int rds6_ib_conn_info_visitor(struct rds_connection *conn, | ||
326 | void *buffer) | ||
327 | { | ||
328 | struct rds6_info_rdma_connection *iinfo6 = buffer; | ||
329 | struct rds_ib_connection *ic; | ||
330 | |||
331 | /* We will only ever look at IB transports */ | ||
332 | if (conn->c_trans != &rds_ib_transport) | ||
333 | return 0; | ||
334 | |||
335 | iinfo6->src_addr = conn->c_laddr; | ||
336 | iinfo6->dst_addr = conn->c_faddr; | ||
337 | |||
338 | memset(&iinfo6->src_gid, 0, sizeof(iinfo6->src_gid)); | ||
339 | memset(&iinfo6->dst_gid, 0, sizeof(iinfo6->dst_gid)); | ||
340 | |||
341 | if (rds_conn_state(conn) == RDS_CONN_UP) { | ||
342 | struct rds_ib_device *rds_ibdev; | ||
343 | struct rdma_dev_addr *dev_addr; | ||
344 | |||
345 | ic = conn->c_transport_data; | ||
346 | dev_addr = &ic->i_cm_id->route.addr.dev_addr; | ||
347 | rdma_addr_get_sgid(dev_addr, | ||
348 | (union ib_gid *)&iinfo6->src_gid); | ||
349 | rdma_addr_get_dgid(dev_addr, | ||
350 | (union ib_gid *)&iinfo6->dst_gid); | ||
351 | |||
352 | rds_ibdev = ic->rds_ibdev; | ||
353 | iinfo6->max_send_wr = ic->i_send_ring.w_nr; | ||
354 | iinfo6->max_recv_wr = ic->i_recv_ring.w_nr; | ||
355 | iinfo6->max_send_sge = rds_ibdev->max_sge; | ||
356 | rds6_ib_get_mr_info(rds_ibdev, iinfo6); | ||
357 | } | ||
358 | return 1; | ||
359 | } | ||
360 | |||
324 | static void rds_ib_ic_info(struct socket *sock, unsigned int len, | 361 | static void rds_ib_ic_info(struct socket *sock, unsigned int len, |
325 | struct rds_info_iterator *iter, | 362 | struct rds_info_iterator *iter, |
326 | struct rds_info_lengths *lens) | 363 | struct rds_info_lengths *lens) |
@@ -333,6 +370,19 @@ static void rds_ib_ic_info(struct socket *sock, unsigned int len, | |||
333 | sizeof(struct rds_info_rdma_connection)); | 370 | sizeof(struct rds_info_rdma_connection)); |
334 | } | 371 | } |
335 | 372 | ||
373 | /* IPv6 version of rds_ib_ic_info(). */ | ||
374 | static void rds6_ib_ic_info(struct socket *sock, unsigned int len, | ||
375 | struct rds_info_iterator *iter, | ||
376 | struct rds_info_lengths *lens) | ||
377 | { | ||
378 | u64 buffer[(sizeof(struct rds6_info_rdma_connection) + 7) / 8]; | ||
379 | |||
380 | rds_for_each_conn_info(sock, len, iter, lens, | ||
381 | rds6_ib_conn_info_visitor, | ||
382 | buffer, | ||
383 | sizeof(struct rds6_info_rdma_connection)); | ||
384 | } | ||
385 | |||
336 | /* | 386 | /* |
337 | * Early RDS/IB was built to only bind to an address if there is an IPoIB | 387 | * Early RDS/IB was built to only bind to an address if there is an IPoIB |
338 | * device with that address set. | 388 | * device with that address set. |
@@ -441,6 +491,7 @@ void rds_ib_exit(void) | |||
441 | rds_ib_set_unloading(); | 491 | rds_ib_set_unloading(); |
442 | synchronize_rcu(); | 492 | synchronize_rcu(); |
443 | rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); | 493 | rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); |
494 | rds_info_deregister_func(RDS6_INFO_IB_CONNECTIONS, rds6_ib_ic_info); | ||
444 | rds_ib_unregister_client(); | 495 | rds_ib_unregister_client(); |
445 | rds_ib_destroy_nodev_conns(); | 496 | rds_ib_destroy_nodev_conns(); |
446 | rds_ib_sysctl_exit(); | 497 | rds_ib_sysctl_exit(); |
@@ -502,6 +553,7 @@ int rds_ib_init(void) | |||
502 | rds_trans_register(&rds_ib_transport); | 553 | rds_trans_register(&rds_ib_transport); |
503 | 554 | ||
504 | rds_info_register_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); | 555 | rds_info_register_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); |
556 | rds_info_register_func(RDS6_INFO_IB_CONNECTIONS, rds6_ib_ic_info); | ||
505 | 557 | ||
506 | goto out; | 558 | goto out; |
507 | 559 | ||
diff --git a/net/rds/ib_mr.h b/net/rds/ib_mr.h index 0ea4ab017a8c..f440ace584c8 100644 --- a/net/rds/ib_mr.h +++ b/net/rds/ib_mr.h | |||
@@ -113,6 +113,8 @@ struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_dev, | |||
113 | int npages); | 113 | int npages); |
114 | void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, | 114 | void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, |
115 | struct rds_info_rdma_connection *iinfo); | 115 | struct rds_info_rdma_connection *iinfo); |
116 | void rds6_ib_get_mr_info(struct rds_ib_device *rds_ibdev, | ||
117 | struct rds6_info_rdma_connection *iinfo6); | ||
116 | void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *); | 118 | void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *); |
117 | void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, | 119 | void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, |
118 | struct rds_sock *rs, u32 *key_ret); | 120 | struct rds_sock *rs, u32 *key_ret); |
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 0ec9df043dd0..e3c8bbbdb43f 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006, 2017 Oracle and/or its affiliates. All rights reserved. | 2 | * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved. |
3 | * | 3 | * |
4 | * This software is available to you under a choice of one of two | 4 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 5 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -180,6 +180,15 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_co | |||
180 | iinfo->rdma_mr_size = pool_1m->fmr_attr.max_pages; | 180 | iinfo->rdma_mr_size = pool_1m->fmr_attr.max_pages; |
181 | } | 181 | } |
182 | 182 | ||
183 | void rds6_ib_get_mr_info(struct rds_ib_device *rds_ibdev, | ||
184 | struct rds6_info_rdma_connection *iinfo6) | ||
185 | { | ||
186 | struct rds_ib_mr_pool *pool_1m = rds_ibdev->mr_1m_pool; | ||
187 | |||
188 | iinfo6->rdma_mr_max = pool_1m->max_items; | ||
189 | iinfo6->rdma_mr_size = pool_1m->fmr_attr.max_pages; | ||
190 | } | ||
191 | |||
183 | struct rds_ib_mr *rds_ib_reuse_mr(struct rds_ib_mr_pool *pool) | 192 | struct rds_ib_mr *rds_ib_reuse_mr(struct rds_ib_mr_pool *pool) |
184 | { | 193 | { |
185 | struct rds_ib_mr *ibmr = NULL; | 194 | struct rds_ib_mr *ibmr = NULL; |
diff --git a/net/rds/recv.c b/net/rds/recv.c index 1402c21210b1..03cd8df54c26 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
@@ -792,3 +792,28 @@ void rds_inc_info_copy(struct rds_incoming *inc, | |||
792 | 792 | ||
793 | rds_info_copy(iter, &minfo, sizeof(minfo)); | 793 | rds_info_copy(iter, &minfo, sizeof(minfo)); |
794 | } | 794 | } |
795 | |||
796 | void rds6_inc_info_copy(struct rds_incoming *inc, | ||
797 | struct rds_info_iterator *iter, | ||
798 | struct in6_addr *saddr, struct in6_addr *daddr, | ||
799 | int flip) | ||
800 | { | ||
801 | struct rds6_info_message minfo6; | ||
802 | |||
803 | minfo6.seq = be64_to_cpu(inc->i_hdr.h_sequence); | ||
804 | minfo6.len = be32_to_cpu(inc->i_hdr.h_len); | ||
805 | |||
806 | if (flip) { | ||
807 | minfo6.laddr = *daddr; | ||
808 | minfo6.faddr = *saddr; | ||
809 | minfo6.lport = inc->i_hdr.h_dport; | ||
810 | minfo6.fport = inc->i_hdr.h_sport; | ||
811 | } else { | ||
812 | minfo6.laddr = *saddr; | ||
813 | minfo6.faddr = *daddr; | ||
814 | minfo6.lport = inc->i_hdr.h_sport; | ||
815 | minfo6.fport = inc->i_hdr.h_dport; | ||
816 | } | ||
817 | |||
818 | rds_info_copy(iter, &minfo6, sizeof(minfo6)); | ||
819 | } | ||
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 890d0e1d8908..7028d6e51947 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
@@ -273,6 +273,48 @@ out: | |||
273 | spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags); | 273 | spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags); |
274 | } | 274 | } |
275 | 275 | ||
276 | /* Handle RDS6_INFO_TCP_SOCKETS socket option. It returns both IPv4 and | ||
277 | * IPv6 connections. IPv4 connection address is returned in an IPv4 mapped | ||
278 | * address. | ||
279 | */ | ||
280 | static void rds6_tcp_tc_info(struct socket *sock, unsigned int len, | ||
281 | struct rds_info_iterator *iter, | ||
282 | struct rds_info_lengths *lens) | ||
283 | { | ||
284 | struct rds6_info_tcp_socket tsinfo6; | ||
285 | struct rds_tcp_connection *tc; | ||
286 | unsigned long flags; | ||
287 | |||
288 | spin_lock_irqsave(&rds_tcp_tc_list_lock, flags); | ||
289 | |||
290 | if (len / sizeof(tsinfo6) < rds6_tcp_tc_count) | ||
291 | goto out; | ||
292 | |||
293 | list_for_each_entry(tc, &rds_tcp_tc_list, t_list_item) { | ||
294 | struct sock *sk = tc->t_sock->sk; | ||
295 | struct inet_sock *inet = inet_sk(sk); | ||
296 | |||
297 | tsinfo6.local_addr = sk->sk_v6_rcv_saddr; | ||
298 | tsinfo6.local_port = inet->inet_sport; | ||
299 | tsinfo6.peer_addr = sk->sk_v6_daddr; | ||
300 | tsinfo6.peer_port = inet->inet_dport; | ||
301 | |||
302 | tsinfo6.hdr_rem = tc->t_tinc_hdr_rem; | ||
303 | tsinfo6.data_rem = tc->t_tinc_data_rem; | ||
304 | tsinfo6.last_sent_nxt = tc->t_last_sent_nxt; | ||
305 | tsinfo6.last_expected_una = tc->t_last_expected_una; | ||
306 | tsinfo6.last_seen_una = tc->t_last_seen_una; | ||
307 | |||
308 | rds_info_copy(iter, &tsinfo6, sizeof(tsinfo6)); | ||
309 | } | ||
310 | |||
311 | out: | ||
312 | lens->nr = rds6_tcp_tc_count; | ||
313 | lens->each = sizeof(tsinfo6); | ||
314 | |||
315 | spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags); | ||
316 | } | ||
317 | |||
276 | static int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr, | 318 | static int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr, |
277 | __u32 scope_id) | 319 | __u32 scope_id) |
278 | { | 320 | { |
@@ -628,6 +670,7 @@ static void rds_tcp_exit(void) | |||
628 | rds_tcp_set_unloading(); | 670 | rds_tcp_set_unloading(); |
629 | synchronize_rcu(); | 671 | synchronize_rcu(); |
630 | rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); | 672 | rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); |
673 | rds_info_deregister_func(RDS6_INFO_TCP_SOCKETS, rds6_tcp_tc_info); | ||
631 | unregister_pernet_device(&rds_tcp_net_ops); | 674 | unregister_pernet_device(&rds_tcp_net_ops); |
632 | rds_tcp_destroy_conns(); | 675 | rds_tcp_destroy_conns(); |
633 | rds_trans_unregister(&rds_tcp_transport); | 676 | rds_trans_unregister(&rds_tcp_transport); |
@@ -659,6 +702,7 @@ static int rds_tcp_init(void) | |||
659 | rds_trans_register(&rds_tcp_transport); | 702 | rds_trans_register(&rds_tcp_transport); |
660 | 703 | ||
661 | rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); | 704 | rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); |
705 | rds_info_register_func(RDS6_INFO_TCP_SOCKETS, rds6_tcp_tc_info); | ||
662 | 706 | ||
663 | goto out; | 707 | goto out; |
664 | out_recv: | 708 | out_recv: |