Browse Source

[retry] Rewrite unrelicensable portions of retry.c

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
47ad8fc1ba
4 changed files with 72 additions and 41 deletions
  1. 26
    10
      src/include/ipxe/retry.h
  2. 2
    2
      src/net/neighbour.c
  3. 41
    27
      src/net/retry.c
  4. 3
    2
      src/net/udp/dhcp.c

+ 26
- 10
src/include/ipxe/retry.h View File

@@ -7,14 +7,14 @@
7 7
  *
8 8
  */
9 9
 
10
-FILE_LICENCE ( GPL2_OR_LATER );
10
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 11
 
12 12
 #include <ipxe/list.h>
13 13
 
14
-/** Default timeout value */
14
+/** Default minimum timeout value (in ticks) */
15 15
 #define DEFAULT_MIN_TIMEOUT ( TICKS_PER_SEC / 4 )
16 16
 
17
-/** Limit after which the timeout will be deemed permanent */
17
+/** Default maximum timeout value (in ticks) */
18 18
 #define DEFAULT_MAX_TIMEOUT ( 10 * TICKS_PER_SEC )
19 19
 
20 20
 /** A retry timer */
@@ -25,16 +25,18 @@ struct retry_timer {
25 25
 	unsigned int running;
26 26
 	/** Timeout value (in ticks) */
27 27
 	unsigned long timeout;
28
-	/** Minimum timeout value (in ticks)
28
+	/** Minimum timeout value (in ticks), or zero to use default
29 29
 	 *
30
-	 * A value of zero means "use default timeout."
30
+	 * The timeout will never be reduced below this value.
31 31
 	 */
32
-	unsigned long min_timeout;
33
-	/** Maximum timeout value before failure (in ticks)
32
+	unsigned long min;
33
+	/** Maximum timeout value (in ticks), or zero to use default
34 34
 	 *
35
-	 * A value of zero means "use default timeout."
35
+	 * The timeout will be deemed permanent (according to the
36
+	 * failure indicator passed to expired()) when it exceeds this
37
+	 * value.
36 38
 	 */
37
-	unsigned long max_timeout;
39
+	unsigned long max;
38 40
 	/** Start time (in ticks) */
39 41
 	unsigned long start;
40 42
 	/** Retry count */
@@ -46,7 +48,7 @@ struct retry_timer {
46 48
 	 *
47 49
 	 * The timer will already be stopped when this method is
48 50
 	 * called.  The failure indicator will be True if the retry
49
-	 * timeout has already exceeded @c MAX_TIMEOUT.
51
+	 * timeout has already exceeded @c max_timeout.
50 52
 	 */
51 53
 	void ( * expired ) ( struct retry_timer *timer, int over );
52 54
 	/** Reference counter
@@ -109,4 +111,18 @@ timer_running ( struct retry_timer *timer ) {
109 111
 	return ( timer->running );
110 112
 }
111 113
 
114
+/**
115
+ * Set minimum and maximum timeouts
116
+ *
117
+ * @v timer		Retry timer
118
+ * @v min		Minimum timeout (in ticks), or zero to use default
119
+ * @v max		Maximum timeout (in ticks), or zero to use default
120
+ */
121
+static inline __attribute__ (( always_inline )) void
122
+set_timer_limits ( struct retry_timer *timer, unsigned long min,
123
+		   unsigned long max ) {
124
+	timer->min = min;
125
+	timer->max = max;
126
+}
127
+
112 128
 #endif /* _IPXE_RETRY_H */

+ 2
- 2
src/net/neighbour.c View File

@@ -95,8 +95,8 @@ static struct neighbour * neighbour_create ( struct net_device *netdev,
95 95
 	memcpy ( neighbour->net_dest, net_dest,
96 96
 		 net_protocol->net_addr_len );
97 97
 	timer_init ( &neighbour->timer, neighbour_expired, &neighbour->refcnt );
98
-	neighbour->timer.min_timeout = NEIGHBOUR_MIN_TIMEOUT;
99
-	neighbour->timer.max_timeout = NEIGHBOUR_MAX_TIMEOUT;
98
+	set_timer_limits ( &neighbour->timer, NEIGHBOUR_MIN_TIMEOUT,
99
+			   NEIGHBOUR_MAX_TIMEOUT );
100 100
 	INIT_LIST_HEAD ( &neighbour->tx_queue );
101 101
 
102 102
 	/* Transfer ownership to cache */

+ 41
- 27
src/net/retry.c View File

@@ -15,9 +15,13 @@
15 15
  * along with this program; if not, write to the Free Software
16 16
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 17
  * 02110-1301, USA.
18
+ *
19
+ * You can also choose to distribute this program under the terms of
20
+ * the Unmodified Binary Distribution Licence (as given in the file
21
+ * COPYING.UBDL), provided that you have satisfied its requirements.
18 22
  */
19 23
 
20
-FILE_LICENCE ( GPL2_OR_LATER );
24
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
21 25
 
22 26
 #include <stddef.h>
23 27
 #include <ipxe/timer.h>
@@ -35,7 +39,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
35 39
  *
36 40
  * This implementation of the timer is designed to satisfy RFC 2988
37 41
  * and therefore be usable as a TCP retransmission timer.
38
- *
39 42
  * 
40 43
  */
41 44
 
@@ -49,47 +52,59 @@ FILE_LICENCE ( GPL2_OR_LATER );
49 52
 static LIST_HEAD ( timers );
50 53
 
51 54
 /**
52
- * Start timer
55
+ * Start timer with a specified timeout
53 56
  *
54 57
  * @v timer		Retry timer
58
+ * @v timeout		Timeout, in ticks
55 59
  *
56
- * This starts the timer running with the current timeout value.  If
60
+ * This starts the timer running with the specified timeout value.  If
57 61
  * stop_timer() is not called before the timer expires, the timer will
58 62
  * be stopped and the timer's callback function will be called.
59 63
  */
60
-void start_timer ( struct retry_timer *timer ) {
64
+void start_timer_fixed ( struct retry_timer *timer, unsigned long timeout ) {
65
+
66
+	/* Add to list of running timers (if applicable) */
61 67
 	if ( ! timer->running ) {
62 68
 		list_add ( &timer->list, &timers );
63 69
 		ref_get ( timer->refcnt );
70
+		timer->running = 1;
64 71
 	}
72
+
73
+	/* Record start time */
65 74
 	timer->start = currticks();
66
-	timer->running = 1;
67
-
68
-	/* 0 means "use default timeout" */
69
-	if ( timer->min_timeout == 0 )
70
-		timer->min_timeout = DEFAULT_MIN_TIMEOUT;
71
-	/* We must never be less than MIN_TIMEOUT under any circumstances */
72
-	if ( timer->min_timeout < MIN_TIMEOUT )
73
-		timer->min_timeout = MIN_TIMEOUT;
74
-	/* Honor user-specified minimum timeout */
75
-	if ( timer->timeout < timer->min_timeout )
76
-		timer->timeout = timer->min_timeout;
75
+
76
+	/* Record timeout */
77
+	timer->timeout = timeout;
77 78
 
78 79
 	DBG2 ( "Timer %p started at time %ld (expires at %ld)\n",
79 80
 	       timer, timer->start, ( timer->start + timer->timeout ) );
80 81
 }
81 82
 
82 83
 /**
83
- * Start timer with a specified fixed timeout
84
+ * Start timer
84 85
  *
85 86
  * @v timer		Retry timer
86
- * @v timeout		Timeout, in ticks
87
+ *
88
+ * This starts the timer running with the current timeout value
89
+ * (rounded up to the minimum timeout value).  If stop_timer() is not
90
+ * called before the timer expires, the timer will be stopped and the
91
+ * timer's callback function will be called.
87 92
  */
88
-void start_timer_fixed ( struct retry_timer *timer, unsigned long timeout ) {
89
-	start_timer ( timer );
90
-	timer->timeout = timeout;
91
-	DBG2 ( "Timer %p expiry time changed to %ld\n",
92
-	       timer, ( timer->start + timer->timeout ) );
93
+void start_timer ( struct retry_timer *timer ) {
94
+	unsigned long timeout = timer->timeout;
95
+	unsigned long min;
96
+
97
+	/* Calculate minimum timeout */
98
+	min = ( timer->min ? timer->min : DEFAULT_MIN_TIMEOUT );
99
+	if ( min < MIN_TIMEOUT )
100
+		min = MIN_TIMEOUT;
101
+
102
+	/* Ensure timeout is at least the minimum */
103
+	if ( timeout < min )
104
+		timeout = min;
105
+
106
+	/* Start timer with this timeout */
107
+	start_timer_fixed ( timer, timeout );
93 108
 }
94 109
 
95 110
 /**
@@ -150,6 +165,7 @@ void stop_timer ( struct retry_timer *timer ) {
150 165
  */
151 166
 static void timer_expired ( struct retry_timer *timer ) {
152 167
 	struct refcnt *refcnt = timer->refcnt;
168
+	unsigned long max = ( timer->max ? timer->max : DEFAULT_MAX_TIMEOUT );
153 169
 	int fail;
154 170
 
155 171
 	/* Stop timer without performing RTT calculations */
@@ -162,10 +178,8 @@ static void timer_expired ( struct retry_timer *timer ) {
162 178
 
163 179
 	/* Back off the timeout value */
164 180
 	timer->timeout <<= 1;
165
-	if ( timer->max_timeout == 0 ) /* 0 means "use default timeout" */
166
-		timer->max_timeout = DEFAULT_MAX_TIMEOUT;
167
-	if ( ( fail = ( timer->timeout > timer->max_timeout ) ) )
168
-		timer->timeout = timer->max_timeout;
181
+	if ( ( fail = ( timer->timeout > max ) ) )
182
+		timer->timeout = max;
169 183
 	DBG ( "Timer %p timeout backed off to %ld\n",
170 184
 	      timer, timer->timeout );
171 185
 

+ 3
- 2
src/net/udp/dhcp.c View File

@@ -278,8 +278,9 @@ static void dhcp_set_state ( struct dhcp_session *dhcp,
278 278
 	dhcp->state = state;
279 279
 	dhcp->start = currticks();
280 280
 	stop_timer ( &dhcp->timer );
281
-	dhcp->timer.min_timeout = state->min_timeout_sec * TICKS_PER_SEC;
282
-	dhcp->timer.max_timeout = state->max_timeout_sec * TICKS_PER_SEC;
281
+	set_timer_limits ( &dhcp->timer,
282
+			   ( state->min_timeout_sec * TICKS_PER_SEC ),
283
+			   ( state->max_timeout_sec * TICKS_PER_SEC ) );
283 284
 	start_timer_nodelay ( &dhcp->timer );
284 285
 }
285 286
 

Loading…
Cancel
Save