diff options
author | David Howells <dhowells@redhat.com> | 2014-02-07 13:58:44 -0500 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2014-02-26 12:25:06 -0500 |
commit | 5873c0834f8896aa9da338b941035a2f8b29e99b (patch) | |
tree | 4faf1ab1a7f95be86c5d9d775b82b6d01012c9a5 | |
parent | 6c9a2d3202973a0266beabc5274c3e67dad5db96 (diff) |
af_rxrpc: Add sysctls for configuring RxRPC parameters
Add sysctls for configuring RxRPC protocol handling, specifically controls on
delays before ack generation, the delay before resending a packet, the maximum
lifetime of a call and the expiration times of calls, connections and
transports that haven't been recently used.
More info added in Documentation/networking/rxrpc.txt.
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | Documentation/networking/rxrpc.txt | 62 | ||||
-rw-r--r-- | net/rxrpc/Makefile | 5 | ||||
-rw-r--r-- | net/rxrpc/af_rxrpc.c | 9 | ||||
-rw-r--r-- | net/rxrpc/ar-ack.c | 35 | ||||
-rw-r--r-- | net/rxrpc/ar-call.c | 18 | ||||
-rw-r--r-- | net/rxrpc/ar-connection.c | 10 | ||||
-rw-r--r-- | net/rxrpc/ar-input.c | 2 | ||||
-rw-r--r-- | net/rxrpc/ar-internal.h | 24 | ||||
-rw-r--r-- | net/rxrpc/ar-output.c | 7 | ||||
-rw-r--r-- | net/rxrpc/ar-skbuff.c | 5 | ||||
-rw-r--r-- | net/rxrpc/ar-transport.c | 10 | ||||
-rw-r--r-- | net/rxrpc/sysctl.c | 113 |
12 files changed, 273 insertions, 27 deletions
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt index b89bc82eed46..aa08d2625f05 100644 --- a/Documentation/networking/rxrpc.txt +++ b/Documentation/networking/rxrpc.txt | |||
@@ -27,6 +27,8 @@ Contents of this document: | |||
27 | 27 | ||
28 | (*) AF_RXRPC kernel interface. | 28 | (*) AF_RXRPC kernel interface. |
29 | 29 | ||
30 | (*) Configurable parameters. | ||
31 | |||
30 | 32 | ||
31 | ======== | 33 | ======== |
32 | OVERVIEW | 34 | OVERVIEW |
@@ -864,3 +866,63 @@ The kernel interface functions are as follows: | |||
864 | 866 | ||
865 | This is used to allocate a null RxRPC key that can be used to indicate | 867 | This is used to allocate a null RxRPC key that can be used to indicate |
866 | anonymous security for a particular domain. | 868 | anonymous security for a particular domain. |
869 | |||
870 | |||
871 | ======================= | ||
872 | CONFIGURABLE PARAMETERS | ||
873 | ======================= | ||
874 | |||
875 | The RxRPC protocol driver has a number of configurable parameters that can be | ||
876 | adjusted through sysctls in /proc/net/rxrpc/: | ||
877 | |||
878 | (*) req_ack_delay | ||
879 | |||
880 | The amount of time in milliseconds after receiving a packet with the | ||
881 | request-ack flag set before we honour the flag and actually send the | ||
882 | requested ack. | ||
883 | |||
884 | Usually the other side won't stop sending packets until the advertised | ||
885 | reception window is full (to a maximum of 255 packets), so delaying the | ||
886 | ACK permits several packets to be ACK'd in one go. | ||
887 | |||
888 | (*) soft_ack_delay | ||
889 | |||
890 | The amount of time in milliseconds after receiving a new packet before we | ||
891 | generate a soft-ACK to tell the sender that it doesn't need to resend. | ||
892 | |||
893 | (*) idle_ack_delay | ||
894 | |||
895 | The amount of time in milliseconds after all the packets currently in the | ||
896 | received queue have been consumed before we generate a hard-ACK to tell | ||
897 | the sender it can free its buffers, assuming no other reason occurs that | ||
898 | we would send an ACK. | ||
899 | |||
900 | (*) resend_timeout | ||
901 | |||
902 | The amount of time in milliseconds after transmitting a packet before we | ||
903 | transmit it again, assuming no ACK is received from the receiver telling | ||
904 | us they got it. | ||
905 | |||
906 | (*) max_call_lifetime | ||
907 | |||
908 | The maximum amount of time in seconds that a call may be in progress | ||
909 | before we preemptively kill it. | ||
910 | |||
911 | (*) dead_call_expiry | ||
912 | |||
913 | The amount of time in seconds before we remove a dead call from the call | ||
914 | list. Dead calls are kept around for a little while for the purpose of | ||
915 | repeating ACK and ABORT packets. | ||
916 | |||
917 | (*) connection_expiry | ||
918 | |||
919 | The amount of time in seconds after a connection was last used before we | ||
920 | remove it from the connection list. Whilst a connection is in existence, | ||
921 | it serves as a placeholder for negotiated security; when it is deleted, | ||
922 | the security must be renegotiated. | ||
923 | |||
924 | (*) transport_expiry | ||
925 | |||
926 | The amount of time in seconds after a transport was last used before we | ||
927 | remove it from the transport list. Whilst a transport is in existence, it | ||
928 | serves to anchor the peer data and keeps the connection ID counter. | ||
diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile index d1c3429b69ed..ec126f91276b 100644 --- a/net/rxrpc/Makefile +++ b/net/rxrpc/Makefile | |||
@@ -20,9 +20,8 @@ af-rxrpc-y := \ | |||
20 | ar-skbuff.o \ | 20 | ar-skbuff.o \ |
21 | ar-transport.o | 21 | ar-transport.o |
22 | 22 | ||
23 | ifeq ($(CONFIG_PROC_FS),y) | 23 | af-rxrpc-$(CONFIG_PROC_FS) += ar-proc.o |
24 | af-rxrpc-y += ar-proc.o | 24 | af-rxrpc-$(CONFIG_SYSCTL) += sysctl.o |
25 | endif | ||
26 | 25 | ||
27 | obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o | 26 | obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o |
28 | 27 | ||
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index e61aa6001c65..7b1670489638 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
@@ -838,6 +838,12 @@ static int __init af_rxrpc_init(void) | |||
838 | goto error_key_type_s; | 838 | goto error_key_type_s; |
839 | } | 839 | } |
840 | 840 | ||
841 | ret = rxrpc_sysctl_init(); | ||
842 | if (ret < 0) { | ||
843 | printk(KERN_CRIT "RxRPC: Cannot register sysctls\n"); | ||
844 | goto error_sysctls; | ||
845 | } | ||
846 | |||
841 | #ifdef CONFIG_PROC_FS | 847 | #ifdef CONFIG_PROC_FS |
842 | proc_create("rxrpc_calls", 0, init_net.proc_net, &rxrpc_call_seq_fops); | 848 | proc_create("rxrpc_calls", 0, init_net.proc_net, &rxrpc_call_seq_fops); |
843 | proc_create("rxrpc_conns", 0, init_net.proc_net, | 849 | proc_create("rxrpc_conns", 0, init_net.proc_net, |
@@ -845,6 +851,8 @@ static int __init af_rxrpc_init(void) | |||
845 | #endif | 851 | #endif |
846 | return 0; | 852 | return 0; |
847 | 853 | ||
854 | error_sysctls: | ||
855 | unregister_key_type(&key_type_rxrpc_s); | ||
848 | error_key_type_s: | 856 | error_key_type_s: |
849 | unregister_key_type(&key_type_rxrpc); | 857 | unregister_key_type(&key_type_rxrpc); |
850 | error_key_type: | 858 | error_key_type: |
@@ -865,6 +873,7 @@ error_call_jar: | |||
865 | static void __exit af_rxrpc_exit(void) | 873 | static void __exit af_rxrpc_exit(void) |
866 | { | 874 | { |
867 | _enter(""); | 875 | _enter(""); |
876 | rxrpc_sysctl_exit(); | ||
868 | unregister_key_type(&key_type_rxrpc_s); | 877 | unregister_key_type(&key_type_rxrpc_s); |
869 | unregister_key_type(&key_type_rxrpc); | 878 | unregister_key_type(&key_type_rxrpc); |
870 | sock_unregister(PF_RXRPC); | 879 | sock_unregister(PF_RXRPC); |
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c index cd97a0ce48d8..732b82f540c5 100644 --- a/net/rxrpc/ar-ack.c +++ b/net/rxrpc/ar-ack.c | |||
@@ -19,7 +19,29 @@ | |||
19 | #include <net/af_rxrpc.h> | 19 | #include <net/af_rxrpc.h> |
20 | #include "ar-internal.h" | 20 | #include "ar-internal.h" |
21 | 21 | ||
22 | static unsigned int rxrpc_ack_defer = 1; | 22 | /* |
23 | * How long to wait before scheduling ACK generation after seeing a | ||
24 | * packet with RXRPC_REQUEST_ACK set (in jiffies). | ||
25 | */ | ||
26 | unsigned rxrpc_requested_ack_delay = 1; | ||
27 | |||
28 | /* | ||
29 | * How long to wait before scheduling an ACK with subtype DELAY (in jiffies). | ||
30 | * | ||
31 | * We use this when we've received new data packets. If those packets aren't | ||
32 | * all consumed within this time we will send a DELAY ACK if an ACK was not | ||
33 | * requested to let the sender know it doesn't need to resend. | ||
34 | */ | ||
35 | unsigned rxrpc_soft_ack_delay = 1 * HZ; | ||
36 | |||
37 | /* | ||
38 | * How long to wait before scheduling an ACK with subtype IDLE (in jiffies). | ||
39 | * | ||
40 | * We use this when we've consumed some previously soft-ACK'd packets when | ||
41 | * further packets aren't immediately received to decide when to send an IDLE | ||
42 | * ACK let the other end know that it can free up its Tx buffer space. | ||
43 | */ | ||
44 | unsigned rxrpc_idle_ack_delay = 1; | ||
23 | 45 | ||
24 | static const char *rxrpc_acks(u8 reason) | 46 | static const char *rxrpc_acks(u8 reason) |
25 | { | 47 | { |
@@ -82,24 +104,23 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, | |||
82 | switch (ack_reason) { | 104 | switch (ack_reason) { |
83 | case RXRPC_ACK_DELAY: | 105 | case RXRPC_ACK_DELAY: |
84 | _debug("run delay timer"); | 106 | _debug("run delay timer"); |
85 | call->ack_timer.expires = jiffies + rxrpc_ack_timeout * HZ; | 107 | expiry = rxrpc_soft_ack_delay; |
86 | add_timer(&call->ack_timer); | 108 | goto run_timer; |
87 | return; | ||
88 | 109 | ||
89 | case RXRPC_ACK_IDLE: | 110 | case RXRPC_ACK_IDLE: |
90 | if (!immediate) { | 111 | if (!immediate) { |
91 | _debug("run defer timer"); | 112 | _debug("run defer timer"); |
92 | expiry = 1; | 113 | expiry = rxrpc_idle_ack_delay; |
93 | goto run_timer; | 114 | goto run_timer; |
94 | } | 115 | } |
95 | goto cancel_timer; | 116 | goto cancel_timer; |
96 | 117 | ||
97 | case RXRPC_ACK_REQUESTED: | 118 | case RXRPC_ACK_REQUESTED: |
98 | if (!rxrpc_ack_defer) | 119 | expiry = rxrpc_requested_ack_delay; |
120 | if (!expiry) | ||
99 | goto cancel_timer; | 121 | goto cancel_timer; |
100 | if (!immediate || serial == cpu_to_be32(1)) { | 122 | if (!immediate || serial == cpu_to_be32(1)) { |
101 | _debug("run defer timer"); | 123 | _debug("run defer timer"); |
102 | expiry = rxrpc_ack_defer; | ||
103 | goto run_timer; | 124 | goto run_timer; |
104 | } | 125 | } |
105 | 126 | ||
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c index a3bbb360a3f9..1e0903a2a0db 100644 --- a/net/rxrpc/ar-call.c +++ b/net/rxrpc/ar-call.c | |||
@@ -16,6 +16,16 @@ | |||
16 | #include <net/af_rxrpc.h> | 16 | #include <net/af_rxrpc.h> |
17 | #include "ar-internal.h" | 17 | #include "ar-internal.h" |
18 | 18 | ||
19 | /* | ||
20 | * Maximum lifetime of a call (in jiffies). | ||
21 | */ | ||
22 | unsigned rxrpc_max_call_lifetime = 60 * HZ; | ||
23 | |||
24 | /* | ||
25 | * Time till dead call expires after last use (in jiffies). | ||
26 | */ | ||
27 | unsigned rxrpc_dead_call_expiry = 2 * HZ; | ||
28 | |||
19 | const char *const rxrpc_call_states[] = { | 29 | const char *const rxrpc_call_states[] = { |
20 | [RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq", | 30 | [RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq", |
21 | [RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl", | 31 | [RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl", |
@@ -38,8 +48,6 @@ const char *const rxrpc_call_states[] = { | |||
38 | struct kmem_cache *rxrpc_call_jar; | 48 | struct kmem_cache *rxrpc_call_jar; |
39 | LIST_HEAD(rxrpc_calls); | 49 | LIST_HEAD(rxrpc_calls); |
40 | DEFINE_RWLOCK(rxrpc_call_lock); | 50 | DEFINE_RWLOCK(rxrpc_call_lock); |
41 | static unsigned int rxrpc_call_max_lifetime = 60; | ||
42 | static unsigned int rxrpc_dead_call_timeout = 2; | ||
43 | 51 | ||
44 | static void rxrpc_destroy_call(struct work_struct *work); | 52 | static void rxrpc_destroy_call(struct work_struct *work); |
45 | static void rxrpc_call_life_expired(unsigned long _call); | 53 | static void rxrpc_call_life_expired(unsigned long _call); |
@@ -132,7 +140,7 @@ static struct rxrpc_call *rxrpc_alloc_client_call( | |||
132 | list_add(&call->error_link, &call->conn->trans->peer->error_targets); | 140 | list_add(&call->error_link, &call->conn->trans->peer->error_targets); |
133 | spin_unlock(&call->conn->trans->peer->lock); | 141 | spin_unlock(&call->conn->trans->peer->lock); |
134 | 142 | ||
135 | call->lifetimer.expires = jiffies + rxrpc_call_max_lifetime * HZ; | 143 | call->lifetimer.expires = jiffies + rxrpc_max_call_lifetime; |
136 | add_timer(&call->lifetimer); | 144 | add_timer(&call->lifetimer); |
137 | 145 | ||
138 | _leave(" = %p", call); | 146 | _leave(" = %p", call); |
@@ -349,7 +357,7 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx, | |||
349 | 357 | ||
350 | _net("CALL incoming %d on CONN %d", call->debug_id, call->conn->debug_id); | 358 | _net("CALL incoming %d on CONN %d", call->debug_id, call->conn->debug_id); |
351 | 359 | ||
352 | call->lifetimer.expires = jiffies + rxrpc_call_max_lifetime * HZ; | 360 | call->lifetimer.expires = jiffies + rxrpc_max_call_lifetime; |
353 | add_timer(&call->lifetimer); | 361 | add_timer(&call->lifetimer); |
354 | _leave(" = %p {%d} [new]", call, call->debug_id); | 362 | _leave(" = %p {%d} [new]", call, call->debug_id); |
355 | return call; | 363 | return call; |
@@ -533,7 +541,7 @@ void rxrpc_release_call(struct rxrpc_call *call) | |||
533 | del_timer_sync(&call->resend_timer); | 541 | del_timer_sync(&call->resend_timer); |
534 | del_timer_sync(&call->ack_timer); | 542 | del_timer_sync(&call->ack_timer); |
535 | del_timer_sync(&call->lifetimer); | 543 | del_timer_sync(&call->lifetimer); |
536 | call->deadspan.expires = jiffies + rxrpc_dead_call_timeout * HZ; | 544 | call->deadspan.expires = jiffies + rxrpc_dead_call_expiry; |
537 | add_timer(&call->deadspan); | 545 | add_timer(&call->deadspan); |
538 | 546 | ||
539 | _leave(""); | 547 | _leave(""); |
diff --git a/net/rxrpc/ar-connection.c b/net/rxrpc/ar-connection.c index 7bf5b5b9e8b9..6631f4f1e39b 100644 --- a/net/rxrpc/ar-connection.c +++ b/net/rxrpc/ar-connection.c | |||
@@ -18,11 +18,15 @@ | |||
18 | #include <net/af_rxrpc.h> | 18 | #include <net/af_rxrpc.h> |
19 | #include "ar-internal.h" | 19 | #include "ar-internal.h" |
20 | 20 | ||
21 | /* | ||
22 | * Time till a connection expires after last use (in seconds). | ||
23 | */ | ||
24 | unsigned rxrpc_connection_expiry = 10 * 60; | ||
25 | |||
21 | static void rxrpc_connection_reaper(struct work_struct *work); | 26 | static void rxrpc_connection_reaper(struct work_struct *work); |
22 | 27 | ||
23 | LIST_HEAD(rxrpc_connections); | 28 | LIST_HEAD(rxrpc_connections); |
24 | DEFINE_RWLOCK(rxrpc_connection_lock); | 29 | DEFINE_RWLOCK(rxrpc_connection_lock); |
25 | static unsigned long rxrpc_connection_timeout = 10 * 60; | ||
26 | static DECLARE_DELAYED_WORK(rxrpc_connection_reap, rxrpc_connection_reaper); | 30 | static DECLARE_DELAYED_WORK(rxrpc_connection_reap, rxrpc_connection_reaper); |
27 | 31 | ||
28 | /* | 32 | /* |
@@ -862,7 +866,7 @@ static void rxrpc_connection_reaper(struct work_struct *work) | |||
862 | 866 | ||
863 | spin_lock(&conn->trans->client_lock); | 867 | spin_lock(&conn->trans->client_lock); |
864 | write_lock(&conn->trans->conn_lock); | 868 | write_lock(&conn->trans->conn_lock); |
865 | reap_time = conn->put_time + rxrpc_connection_timeout; | 869 | reap_time = conn->put_time + rxrpc_connection_expiry; |
866 | 870 | ||
867 | if (atomic_read(&conn->usage) > 0) { | 871 | if (atomic_read(&conn->usage) > 0) { |
868 | ; | 872 | ; |
@@ -916,7 +920,7 @@ void __exit rxrpc_destroy_all_connections(void) | |||
916 | { | 920 | { |
917 | _enter(""); | 921 | _enter(""); |
918 | 922 | ||
919 | rxrpc_connection_timeout = 0; | 923 | rxrpc_connection_expiry = 0; |
920 | cancel_delayed_work(&rxrpc_connection_reap); | 924 | cancel_delayed_work(&rxrpc_connection_reap); |
921 | rxrpc_queue_delayed_work(&rxrpc_connection_reap, 0); | 925 | rxrpc_queue_delayed_work(&rxrpc_connection_reap, 0); |
922 | 926 | ||
diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c index eb7e16276cc1..540c03d338c9 100644 --- a/net/rxrpc/ar-input.c +++ b/net/rxrpc/ar-input.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include <net/net_namespace.h> | 25 | #include <net/net_namespace.h> |
26 | #include "ar-internal.h" | 26 | #include "ar-internal.h" |
27 | 27 | ||
28 | unsigned long rxrpc_ack_timeout = 1; | ||
29 | |||
30 | const char *rxrpc_pkts[] = { | 28 | const char *rxrpc_pkts[] = { |
31 | "?00", | 29 | "?00", |
32 | "DATA", "ACK", "BUSY", "ABORT", "ACKALL", "CHALL", "RESP", "DEBUG", | 30 | "DATA", "ACK", "BUSY", "ABORT", "ACKALL", "CHALL", "RESP", "DEBUG", |
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 5f43675ee1df..036e1dd84223 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h | |||
@@ -433,6 +433,10 @@ int rxrpc_reject_call(struct rxrpc_sock *); | |||
433 | /* | 433 | /* |
434 | * ar-ack.c | 434 | * ar-ack.c |
435 | */ | 435 | */ |
436 | extern unsigned rxrpc_requested_ack_delay; | ||
437 | extern unsigned rxrpc_soft_ack_delay; | ||
438 | extern unsigned rxrpc_idle_ack_delay; | ||
439 | |||
436 | void __rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool); | 440 | void __rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool); |
437 | void rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool); | 441 | void rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool); |
438 | void rxrpc_process_call(struct work_struct *); | 442 | void rxrpc_process_call(struct work_struct *); |
@@ -440,6 +444,8 @@ void rxrpc_process_call(struct work_struct *); | |||
440 | /* | 444 | /* |
441 | * ar-call.c | 445 | * ar-call.c |
442 | */ | 446 | */ |
447 | extern unsigned rxrpc_max_call_lifetime; | ||
448 | extern unsigned rxrpc_dead_call_expiry; | ||
443 | extern struct kmem_cache *rxrpc_call_jar; | 449 | extern struct kmem_cache *rxrpc_call_jar; |
444 | extern struct list_head rxrpc_calls; | 450 | extern struct list_head rxrpc_calls; |
445 | extern rwlock_t rxrpc_call_lock; | 451 | extern rwlock_t rxrpc_call_lock; |
@@ -460,6 +466,7 @@ void __exit rxrpc_destroy_all_calls(void); | |||
460 | /* | 466 | /* |
461 | * ar-connection.c | 467 | * ar-connection.c |
462 | */ | 468 | */ |
469 | extern unsigned rxrpc_connection_expiry; | ||
463 | extern struct list_head rxrpc_connections; | 470 | extern struct list_head rxrpc_connections; |
464 | extern rwlock_t rxrpc_connection_lock; | 471 | extern rwlock_t rxrpc_connection_lock; |
465 | 472 | ||
@@ -493,7 +500,6 @@ void rxrpc_UDP_error_handler(struct work_struct *); | |||
493 | /* | 500 | /* |
494 | * ar-input.c | 501 | * ar-input.c |
495 | */ | 502 | */ |
496 | extern unsigned long rxrpc_ack_timeout; | ||
497 | extern const char *rxrpc_pkts[]; | 503 | extern const char *rxrpc_pkts[]; |
498 | 504 | ||
499 | void rxrpc_data_ready(struct sock *, int); | 505 | void rxrpc_data_ready(struct sock *, int); |
@@ -504,6 +510,7 @@ void rxrpc_fast_process_packet(struct rxrpc_call *, struct sk_buff *); | |||
504 | * ar-local.c | 510 | * ar-local.c |
505 | */ | 511 | */ |
506 | extern rwlock_t rxrpc_local_lock; | 512 | extern rwlock_t rxrpc_local_lock; |
513 | |||
507 | struct rxrpc_local *rxrpc_lookup_local(struct sockaddr_rxrpc *); | 514 | struct rxrpc_local *rxrpc_lookup_local(struct sockaddr_rxrpc *); |
508 | void rxrpc_put_local(struct rxrpc_local *); | 515 | void rxrpc_put_local(struct rxrpc_local *); |
509 | void __exit rxrpc_destroy_all_locals(void); | 516 | void __exit rxrpc_destroy_all_locals(void); |
@@ -522,7 +529,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *, const void *, time_t, | |||
522 | /* | 529 | /* |
523 | * ar-output.c | 530 | * ar-output.c |
524 | */ | 531 | */ |
525 | extern int rxrpc_resend_timeout; | 532 | extern unsigned rxrpc_resend_timeout; |
526 | 533 | ||
527 | int rxrpc_send_packet(struct rxrpc_transport *, struct sk_buff *); | 534 | int rxrpc_send_packet(struct rxrpc_transport *, struct sk_buff *); |
528 | int rxrpc_client_sendmsg(struct kiocb *, struct rxrpc_sock *, | 535 | int rxrpc_client_sendmsg(struct kiocb *, struct rxrpc_sock *, |
@@ -572,6 +579,8 @@ void rxrpc_packet_destructor(struct sk_buff *); | |||
572 | /* | 579 | /* |
573 | * ar-transport.c | 580 | * ar-transport.c |
574 | */ | 581 | */ |
582 | extern unsigned rxrpc_transport_expiry; | ||
583 | |||
575 | struct rxrpc_transport *rxrpc_get_transport(struct rxrpc_local *, | 584 | struct rxrpc_transport *rxrpc_get_transport(struct rxrpc_local *, |
576 | struct rxrpc_peer *, gfp_t); | 585 | struct rxrpc_peer *, gfp_t); |
577 | void rxrpc_put_transport(struct rxrpc_transport *); | 586 | void rxrpc_put_transport(struct rxrpc_transport *); |
@@ -580,6 +589,17 @@ struct rxrpc_transport *rxrpc_find_transport(struct rxrpc_local *, | |||
580 | struct rxrpc_peer *); | 589 | struct rxrpc_peer *); |
581 | 590 | ||
582 | /* | 591 | /* |
592 | * sysctl.c | ||
593 | */ | ||
594 | #ifdef CONFIG_SYSCTL | ||
595 | extern int __init rxrpc_sysctl_init(void); | ||
596 | extern void rxrpc_sysctl_exit(void); | ||
597 | #else | ||
598 | static inline int __init rxrpc_sysctl_init(void) { return 0; } | ||
599 | static inline void rxrpc_sysctl_exit(void) {} | ||
600 | #endif | ||
601 | |||
602 | /* | ||
583 | * debug tracing | 603 | * debug tracing |
584 | */ | 604 | */ |
585 | extern unsigned int rxrpc_debug; | 605 | extern unsigned int rxrpc_debug; |
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c index d0e8f1c1898a..4814d882bcb4 100644 --- a/net/rxrpc/ar-output.c +++ b/net/rxrpc/ar-output.c | |||
@@ -18,7 +18,10 @@ | |||
18 | #include <net/af_rxrpc.h> | 18 | #include <net/af_rxrpc.h> |
19 | #include "ar-internal.h" | 19 | #include "ar-internal.h" |
20 | 20 | ||
21 | int rxrpc_resend_timeout = 4; | 21 | /* |
22 | * Time till packet resend (in jiffies). | ||
23 | */ | ||
24 | unsigned rxrpc_resend_timeout = 4 * HZ; | ||
22 | 25 | ||
23 | static int rxrpc_send_data(struct kiocb *iocb, | 26 | static int rxrpc_send_data(struct kiocb *iocb, |
24 | struct rxrpc_sock *rx, | 27 | struct rxrpc_sock *rx, |
@@ -487,7 +490,7 @@ static void rxrpc_queue_packet(struct rxrpc_call *call, struct sk_buff *skb, | |||
487 | ntohl(sp->hdr.serial), ntohl(sp->hdr.seq)); | 490 | ntohl(sp->hdr.serial), ntohl(sp->hdr.seq)); |
488 | 491 | ||
489 | sp->need_resend = false; | 492 | sp->need_resend = false; |
490 | sp->resend_at = jiffies + rxrpc_resend_timeout * HZ; | 493 | sp->resend_at = jiffies + rxrpc_resend_timeout; |
491 | if (!test_and_set_bit(RXRPC_CALL_RUN_RTIMER, &call->flags)) { | 494 | if (!test_and_set_bit(RXRPC_CALL_RUN_RTIMER, &call->flags)) { |
492 | _debug("run timer"); | 495 | _debug("run timer"); |
493 | call->resend_timer.expires = sp->resend_at; | 496 | call->resend_timer.expires = sp->resend_at; |
diff --git a/net/rxrpc/ar-skbuff.c b/net/rxrpc/ar-skbuff.c index de755e04d29c..af9f4fd2a365 100644 --- a/net/rxrpc/ar-skbuff.c +++ b/net/rxrpc/ar-skbuff.c | |||
@@ -83,6 +83,11 @@ static void rxrpc_hard_ACK_data(struct rxrpc_call *call, | |||
83 | rxrpc_request_final_ACK(call); | 83 | rxrpc_request_final_ACK(call); |
84 | } else if (atomic_dec_and_test(&call->ackr_not_idle) && | 84 | } else if (atomic_dec_and_test(&call->ackr_not_idle) && |
85 | test_and_clear_bit(RXRPC_CALL_TX_SOFT_ACK, &call->flags)) { | 85 | test_and_clear_bit(RXRPC_CALL_TX_SOFT_ACK, &call->flags)) { |
86 | /* We previously soft-ACK'd some received packets that have now | ||
87 | * been consumed, so send a hard-ACK if no more packets are | ||
88 | * immediately forthcoming to allow the transmitter to free up | ||
89 | * its Tx bufferage. | ||
90 | */ | ||
86 | _debug("send Rx idle ACK"); | 91 | _debug("send Rx idle ACK"); |
87 | __rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, sp->hdr.serial, | 92 | __rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, sp->hdr.serial, |
88 | true); | 93 | true); |
diff --git a/net/rxrpc/ar-transport.c b/net/rxrpc/ar-transport.c index 92df566930b9..1976dec84f29 100644 --- a/net/rxrpc/ar-transport.c +++ b/net/rxrpc/ar-transport.c | |||
@@ -17,11 +17,15 @@ | |||
17 | #include <net/af_rxrpc.h> | 17 | #include <net/af_rxrpc.h> |
18 | #include "ar-internal.h" | 18 | #include "ar-internal.h" |
19 | 19 | ||
20 | /* | ||
21 | * Time after last use at which transport record is cleaned up. | ||
22 | */ | ||
23 | unsigned rxrpc_transport_expiry = 3600 * 24; | ||
24 | |||
20 | static void rxrpc_transport_reaper(struct work_struct *work); | 25 | static void rxrpc_transport_reaper(struct work_struct *work); |
21 | 26 | ||
22 | static LIST_HEAD(rxrpc_transports); | 27 | static LIST_HEAD(rxrpc_transports); |
23 | static DEFINE_RWLOCK(rxrpc_transport_lock); | 28 | static DEFINE_RWLOCK(rxrpc_transport_lock); |
24 | static unsigned long rxrpc_transport_timeout = 3600 * 24; | ||
25 | static DECLARE_DELAYED_WORK(rxrpc_transport_reap, rxrpc_transport_reaper); | 29 | static DECLARE_DELAYED_WORK(rxrpc_transport_reap, rxrpc_transport_reaper); |
26 | 30 | ||
27 | /* | 31 | /* |
@@ -235,7 +239,7 @@ static void rxrpc_transport_reaper(struct work_struct *work) | |||
235 | if (likely(atomic_read(&trans->usage) > 0)) | 239 | if (likely(atomic_read(&trans->usage) > 0)) |
236 | continue; | 240 | continue; |
237 | 241 | ||
238 | reap_time = trans->put_time + rxrpc_transport_timeout; | 242 | reap_time = trans->put_time + rxrpc_transport_expiry; |
239 | if (reap_time <= now) | 243 | if (reap_time <= now) |
240 | list_move_tail(&trans->link, &graveyard); | 244 | list_move_tail(&trans->link, &graveyard); |
241 | else if (reap_time < earliest) | 245 | else if (reap_time < earliest) |
@@ -271,7 +275,7 @@ void __exit rxrpc_destroy_all_transports(void) | |||
271 | { | 275 | { |
272 | _enter(""); | 276 | _enter(""); |
273 | 277 | ||
274 | rxrpc_transport_timeout = 0; | 278 | rxrpc_transport_expiry = 0; |
275 | cancel_delayed_work(&rxrpc_transport_reap); | 279 | cancel_delayed_work(&rxrpc_transport_reap); |
276 | rxrpc_queue_delayed_work(&rxrpc_transport_reap, 0); | 280 | rxrpc_queue_delayed_work(&rxrpc_transport_reap, 0); |
277 | 281 | ||
diff --git a/net/rxrpc/sysctl.c b/net/rxrpc/sysctl.c new file mode 100644 index 000000000000..cdc85e72af5d --- /dev/null +++ b/net/rxrpc/sysctl.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /* sysctls for configuring RxRPC operating parameters | ||
2 | * | ||
3 | * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/sysctl.h> | ||
13 | #include <net/sock.h> | ||
14 | #include <net/af_rxrpc.h> | ||
15 | #include "ar-internal.h" | ||
16 | |||
17 | static struct ctl_table_header *rxrpc_sysctl_reg_table; | ||
18 | static const unsigned zero = 0; | ||
19 | static const unsigned one = 1; | ||
20 | |||
21 | /* | ||
22 | * RxRPC operating parameters. | ||
23 | * | ||
24 | * See Documentation/networking/rxrpc.txt and the variable definitions for more | ||
25 | * information on the individual parameters. | ||
26 | */ | ||
27 | static struct ctl_table rxrpc_sysctl_table[] = { | ||
28 | /* Values measured in milliseconds */ | ||
29 | { | ||
30 | .procname = "req_ack_delay", | ||
31 | .data = &rxrpc_requested_ack_delay, | ||
32 | .maxlen = sizeof(unsigned), | ||
33 | .mode = 0644, | ||
34 | .proc_handler = proc_dointvec_ms_jiffies, | ||
35 | .extra1 = (void *)&zero, | ||
36 | }, | ||
37 | { | ||
38 | .procname = "soft_ack_delay", | ||
39 | .data = &rxrpc_soft_ack_delay, | ||
40 | .maxlen = sizeof(unsigned), | ||
41 | .mode = 0644, | ||
42 | .proc_handler = proc_dointvec_ms_jiffies, | ||
43 | .extra1 = (void *)&one, | ||
44 | }, | ||
45 | { | ||
46 | .procname = "idle_ack_delay", | ||
47 | .data = &rxrpc_idle_ack_delay, | ||
48 | .maxlen = sizeof(unsigned), | ||
49 | .mode = 0644, | ||
50 | .proc_handler = proc_dointvec_ms_jiffies, | ||
51 | .extra1 = (void *)&one, | ||
52 | }, | ||
53 | { | ||
54 | .procname = "resend_timeout", | ||
55 | .data = &rxrpc_resend_timeout, | ||
56 | .maxlen = sizeof(unsigned), | ||
57 | .mode = 0644, | ||
58 | .proc_handler = proc_dointvec_ms_jiffies, | ||
59 | .extra1 = (void *)&one, | ||
60 | }, | ||
61 | |||
62 | /* Values measured in seconds but used in jiffies */ | ||
63 | { | ||
64 | .procname = "max_call_lifetime", | ||
65 | .data = &rxrpc_max_call_lifetime, | ||
66 | .maxlen = sizeof(unsigned), | ||
67 | .mode = 0644, | ||
68 | .proc_handler = proc_dointvec_jiffies, | ||
69 | .extra1 = (void *)&one, | ||
70 | }, | ||
71 | { | ||
72 | .procname = "dead_call_expiry", | ||
73 | .data = &rxrpc_dead_call_expiry, | ||
74 | .maxlen = sizeof(unsigned), | ||
75 | .mode = 0644, | ||
76 | .proc_handler = proc_dointvec_jiffies, | ||
77 | .extra1 = (void *)&one, | ||
78 | }, | ||
79 | |||
80 | /* Values measured in seconds */ | ||
81 | { | ||
82 | .procname = "connection_expiry", | ||
83 | .data = &rxrpc_connection_expiry, | ||
84 | .maxlen = sizeof(unsigned), | ||
85 | .mode = 0644, | ||
86 | .proc_handler = proc_dointvec_minmax, | ||
87 | .extra1 = (void *)&one, | ||
88 | }, | ||
89 | { | ||
90 | .procname = "transport_expiry", | ||
91 | .data = &rxrpc_transport_expiry, | ||
92 | .maxlen = sizeof(unsigned), | ||
93 | .mode = 0644, | ||
94 | .proc_handler = proc_dointvec_minmax, | ||
95 | .extra1 = (void *)&one, | ||
96 | }, | ||
97 | { } | ||
98 | }; | ||
99 | |||
100 | int __init rxrpc_sysctl_init(void) | ||
101 | { | ||
102 | rxrpc_sysctl_reg_table = register_net_sysctl(&init_net, "net/rxrpc", | ||
103 | rxrpc_sysctl_table); | ||
104 | if (!rxrpc_sysctl_reg_table) | ||
105 | return -ENOMEM; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | void rxrpc_sysctl_exit(void) | ||
110 | { | ||
111 | if (rxrpc_sysctl_reg_table) | ||
112 | unregister_net_sysctl_table(rxrpc_sysctl_reg_table); | ||
113 | } | ||