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
  *
7
  *
8
  */
8
  */
9
 
9
 
10
-FILE_LICENCE ( GPL2_OR_LATER );
10
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
 
11
 
12
 #include <ipxe/list.h>
12
 #include <ipxe/list.h>
13
 
13
 
14
-/** Default timeout value */
14
+/** Default minimum timeout value (in ticks) */
15
 #define DEFAULT_MIN_TIMEOUT ( TICKS_PER_SEC / 4 )
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
 #define DEFAULT_MAX_TIMEOUT ( 10 * TICKS_PER_SEC )
18
 #define DEFAULT_MAX_TIMEOUT ( 10 * TICKS_PER_SEC )
19
 
19
 
20
 /** A retry timer */
20
 /** A retry timer */
25
 	unsigned int running;
25
 	unsigned int running;
26
 	/** Timeout value (in ticks) */
26
 	/** Timeout value (in ticks) */
27
 	unsigned long timeout;
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
 	/** Start time (in ticks) */
40
 	/** Start time (in ticks) */
39
 	unsigned long start;
41
 	unsigned long start;
40
 	/** Retry count */
42
 	/** Retry count */
46
 	 *
48
 	 *
47
 	 * The timer will already be stopped when this method is
49
 	 * The timer will already be stopped when this method is
48
 	 * called.  The failure indicator will be True if the retry
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
 	void ( * expired ) ( struct retry_timer *timer, int over );
53
 	void ( * expired ) ( struct retry_timer *timer, int over );
52
 	/** Reference counter
54
 	/** Reference counter
109
 	return ( timer->running );
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
 #endif /* _IPXE_RETRY_H */
128
 #endif /* _IPXE_RETRY_H */

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

95
 	memcpy ( neighbour->net_dest, net_dest,
95
 	memcpy ( neighbour->net_dest, net_dest,
96
 		 net_protocol->net_addr_len );
96
 		 net_protocol->net_addr_len );
97
 	timer_init ( &neighbour->timer, neighbour_expired, &neighbour->refcnt );
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
 	INIT_LIST_HEAD ( &neighbour->tx_queue );
100
 	INIT_LIST_HEAD ( &neighbour->tx_queue );
101
 
101
 
102
 	/* Transfer ownership to cache */
102
 	/* Transfer ownership to cache */

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

15
  * along with this program; if not, write to the Free Software
15
  * along with this program; if not, write to the Free Software
16
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
  * 02110-1301, USA.
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
 #include <stddef.h>
26
 #include <stddef.h>
23
 #include <ipxe/timer.h>
27
 #include <ipxe/timer.h>
35
  *
39
  *
36
  * This implementation of the timer is designed to satisfy RFC 2988
40
  * This implementation of the timer is designed to satisfy RFC 2988
37
  * and therefore be usable as a TCP retransmission timer.
41
  * and therefore be usable as a TCP retransmission timer.
38
- *
39
  * 
42
  * 
40
  */
43
  */
41
 
44
 
49
 static LIST_HEAD ( timers );
52
 static LIST_HEAD ( timers );
50
 
53
 
51
 /**
54
 /**
52
- * Start timer
55
+ * Start timer with a specified timeout
53
  *
56
  *
54
  * @v timer		Retry timer
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
  * stop_timer() is not called before the timer expires, the timer will
61
  * stop_timer() is not called before the timer expires, the timer will
58
  * be stopped and the timer's callback function will be called.
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
 	if ( ! timer->running ) {
67
 	if ( ! timer->running ) {
62
 		list_add ( &timer->list, &timers );
68
 		list_add ( &timer->list, &timers );
63
 		ref_get ( timer->refcnt );
69
 		ref_get ( timer->refcnt );
70
+		timer->running = 1;
64
 	}
71
 	}
72
+
73
+	/* Record start time */
65
 	timer->start = currticks();
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
 	DBG2 ( "Timer %p started at time %ld (expires at %ld)\n",
79
 	DBG2 ( "Timer %p started at time %ld (expires at %ld)\n",
79
 	       timer, timer->start, ( timer->start + timer->timeout ) );
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
  * @v timer		Retry timer
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
  */
165
  */
151
 static void timer_expired ( struct retry_timer *timer ) {
166
 static void timer_expired ( struct retry_timer *timer ) {
152
 	struct refcnt *refcnt = timer->refcnt;
167
 	struct refcnt *refcnt = timer->refcnt;
168
+	unsigned long max = ( timer->max ? timer->max : DEFAULT_MAX_TIMEOUT );
153
 	int fail;
169
 	int fail;
154
 
170
 
155
 	/* Stop timer without performing RTT calculations */
171
 	/* Stop timer without performing RTT calculations */
162
 
178
 
163
 	/* Back off the timeout value */
179
 	/* Back off the timeout value */
164
 	timer->timeout <<= 1;
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
 	DBG ( "Timer %p timeout backed off to %ld\n",
183
 	DBG ( "Timer %p timeout backed off to %ld\n",
170
 	      timer, timer->timeout );
184
 	      timer, timer->timeout );
171
 
185
 

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

278
 	dhcp->state = state;
278
 	dhcp->state = state;
279
 	dhcp->start = currticks();
279
 	dhcp->start = currticks();
280
 	stop_timer ( &dhcp->timer );
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
 	start_timer_nodelay ( &dhcp->timer );
284
 	start_timer_nodelay ( &dhcp->timer );
284
 }
285
 }
285
 
286
 

Loading…
Cancel
Save