iPXE
retry.c File Reference

Retry timers. More...

#include <stddef.h>
#include <ipxe/timer.h>
#include <ipxe/list.h>
#include <ipxe/process.h>
#include <ipxe/init.h>
#include <ipxe/retry.h>

Go to the source code of this file.

Macros

#define MIN_TIMEOUT   7

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static LIST_HEAD (timers)
 List of running timers.
void start_timer_fixed (struct retry_timer *timer, unsigned long timeout)
 Start timer with a specified timeout.
void start_timer (struct retry_timer *timer)
 Start timer.
void stop_timer (struct retry_timer *timer)
 Stop timer.
static void timer_expired (struct retry_timer *timer)
 Handle expired timer.
void retry_poll (void)
 Poll the retry timer list.
static void retry_step (struct process *process __unused)
 Single-step the retry timer list.
 PERMANENT_PROCESS (retry_process, retry_step)
 Retry timer process.

Detailed Description

Retry timers.

A retry timer is a binary exponential backoff timer. It can be used to build automatic retransmission into network protocols.

This implementation of the timer is designed to satisfy RFC 2988 and therefore be usable as a TCP retransmission timer.

Definition in file retry.c.

Macro Definition Documentation

◆ MIN_TIMEOUT

#define MIN_TIMEOUT   7

Definition at line 50 of file retry.c.

Referenced by start_timer().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ LIST_HEAD()

LIST_HEAD ( timers )
static

List of running timers.

◆ start_timer_fixed()

void start_timer_fixed ( struct retry_timer * timer,
unsigned long timeout )

Start timer with a specified timeout.

Parameters
timerRetry timer
timeoutTimeout, in ticks

This starts the timer running with the specified timeout value. If stop_timer() is not called before the timer expires, the timer will be stopped and the timer's callback function will be called.

Definition at line 65 of file retry.c.

65 {
66
67 /* Add to list of running timers (if applicable) */
68 if ( ! timer->running ) {
69 list_add ( &timer->list, &timers );
70 ref_get ( timer->refcnt );
71 timer->running = 1;
72 }
73
74 /* Record start time */
75 timer->start = currticks();
76
77 /* Record timeout */
78 timer->timeout = timeout;
79
80 DBGC2 ( timer, "Timer %p started at time %ld (expires at %ld)\n",
81 timer, timer->start, ( timer->start + timer->timeout ) );
82}
void timeout(int)
#define DBGC2(...)
Definition compiler.h:522
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
A timer.
Definition timer.h:29
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43

References currticks(), DBGC2, list_add, ref_get, and timeout().

Referenced by bnxt_er_task(), bnxt_er_task_timer(), bnxt_process_er_event(), cgem_expired(), cgem_open(), dhcp_defer(), eapol_eap_rx(), eapol_expired(), efi_watchdog_expired(), exanic_expired(), exanic_open(), fc_link_err(), fc_link_expired(), fc_xchg_rx(), fc_xchg_tx(), fcoe_expired(), fragment_reassemble(), gve_open(), gve_watchdog(), http_transfer_complete(), http_watchdog(), ipair_rx_pair_error(), iphone_expired(), ipv6conf_expired(), neighbour_tx_queue(), netdev_link_block(), peerblk_open(), peerblk_raw_open(), peerblk_raw_rx(), peerblk_retrieval_open(), peerblk_retrieval_rx(), peerdisc_expired(), pinger_expired(), pool_add(), sandev_command(), slam_mc_socket_deliver(), slam_open(), slirp_timer_mod(), start_timer(), start_timer_nodelay(), tcp_keepalive_expired(), tcp_rx(), tcp_rx_ack(), xcm_keepalive(), xcm_reopen(), xsigo_discover(), xsigo_ib_open(), and xsigo_xcm_complete().

◆ start_timer()

void start_timer ( struct retry_timer * timer)

Start timer.

Parameters
timerRetry timer

This starts the timer running with the current timeout value (rounded up to the minimum timeout value). If stop_timer() is not called before the timer expires, the timer will be stopped and the timer's callback function will be called.

Definition at line 94 of file retry.c.

94 {
95 unsigned long timeout = timer->timeout;
96 unsigned long min;
97
98 /* Calculate minimum timeout */
99 min = ( timer->min ? timer->min : DEFAULT_MIN_TIMEOUT );
100 if ( min < MIN_TIMEOUT )
102
103 /* Ensure timeout is at least the minimum */
104 if ( timeout < min )
105 timeout = min;
106
107 /* Start timer with this timeout */
109}
#define min(x, y)
Definition ath.h:36
#define MIN_TIMEOUT
Definition retry.c:50
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition retry.c:65
#define DEFAULT_MIN_TIMEOUT
Default minimum timeout value (in ticks)
Definition retry.h:16

References DEFAULT_MIN_TIMEOUT, min, MIN_TIMEOUT, start_timer_fixed(), and timeout().

Referenced by aoecmd_tx(), dhcp_tx(), dhcpv6_timer_expired(), dns_send_packet(), ib_mi_timer_expired(), ipv6conf_expired(), neighbour_expired(), ntp_expired(), slam_master_timer_expired(), slam_slave_timer_expired(), slam_socket_deliver(), tcp_xmit_sack(), tftp_send_packet(), xcm_close(), and xcm_reopen().

◆ stop_timer()

void stop_timer ( struct retry_timer * timer)

Stop timer.

Parameters
timerRetry timer

This stops the timer and updates the timer's timeout value.

Definition at line 118 of file retry.c.

118 {
119 unsigned long old_timeout = timer->timeout;
120 unsigned long now = currticks();
121 unsigned long runtime;
122
123 /* If timer was already stopped, do nothing */
124 if ( ! timer->running )
125 return;
126
127 list_del ( &timer->list );
128 runtime = ( now - timer->start );
129 timer->running = 0;
130 DBGC2 ( timer, "Timer %p stopped at time %ld (ran for %ld)\n",
131 timer, now, runtime );
132
133 /* Update timer. Variables are:
134 *
135 * r = round-trip time estimate (i.e. runtime)
136 * t = timeout value (i.e. timer->timeout)
137 * s = smoothed round-trip time
138 *
139 * By choice, we set t = 4s, i.e. allow for four times the
140 * normal round-trip time to pass before retransmitting.
141 *
142 * We want to smooth according to s := ( 7 s + r ) / 8
143 *
144 * Since we don't actually store s, this reduces to
145 * t := ( 7 t / 8 ) + ( r / 2 )
146 *
147 */
148 if ( timer->count ) {
149 timer->count--;
150 } else {
151 timer->timeout -= ( timer->timeout >> 3 );
152 timer->timeout += ( runtime >> 1 );
153 if ( timer->timeout != old_timeout ) {
154 DBGC ( timer, "Timer %p timeout updated to %ld\n",
155 timer, timer->timeout );
156 }
157 }
158
159 ref_put ( timer->refcnt );
160}
#define DBGC(...)
Definition compiler.h:505
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107

References currticks(), DBGC, DBGC2, list_del, and ref_put.

Referenced by aoecmd_close(), bnxt_close(), bnxt_er_task(), bnxt_er_wait_timer(), bnxt_process_er_event(), cgem_close(), dhcp_finished(), dhcp_set_state(), dhcpv6_finished(), dns_done(), eapol_eap_rx(), eapol_notify(), efi_watchdog_stop(), exanic_close(), fc_link_stop(), fc_link_up(), fc_xchg_close(), fcoe_close(), fcoe_expired(), fcoe_reset(), fragment_reassemble(), gve_close(), http_close(), http_transfer_complete(), ib_destroy_madx(), ipair_close(), iphone_close(), ipv6conf_done(), ipv6conf_rx_router_advertisement(), neighbour_destroy(), neighbour_tx_queue(), netdev_close(), netdev_link_err(), netdev_link_unblock(), ntp_close(), peerblk_reset(), peerblk_retrieval_close(), peerdisc_destroy(), pinger_close(), pool_del(), sandev_command_close(), slam_finished(), slam_mc_socket_deliver(), slam_socket_deliver(), slirp_timer_free(), tcp_close(), tcp_rx(), tcp_rx_ack(), tftp_done(), tftp_send_packet(), xcm_close(), xcm_destroy(), xcm_reopen(), xsigo_ib_notify(), and xsigo_ib_remove().

◆ timer_expired()

void timer_expired ( struct retry_timer * timer)
static

Handle expired timer.

Parameters
timerRetry timer

Definition at line 167 of file retry.c.

167 {
168 struct refcnt *refcnt = timer->refcnt;
169 unsigned long max = ( timer->max ? timer->max : DEFAULT_MAX_TIMEOUT );
170 int fail;
171
172 /* Stop timer without performing RTT calculations */
173 DBGC2 ( timer, "Timer %p stopped at time %ld on expiry\n",
174 timer, currticks() );
175 assert ( timer->running );
176 list_del ( &timer->list );
177 timer->running = 0;
178 timer->count++;
179
180 /* Back off the timeout value */
181 timer->timeout <<= 1;
182 if ( ( fail = ( timer->timeout > max ) ) )
183 timer->timeout = max;
184 DBGC ( timer, "Timer %p timeout backed off to %ld\n",
185 timer, timer->timeout );
186
187 /* Call expiry callback */
188 timer->expired ( timer, fail );
189 /* If refcnt is NULL, then timer may already have been freed */
190
191 ref_put ( refcnt );
192}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define max(x, y)
Definition ath.h:41
#define DEFAULT_MAX_TIMEOUT
Default maximum timeout value (in ticks)
Definition retry.h:19
A reference counter.
Definition refcnt.h:27

References assert, currticks(), DBGC, DBGC2, DEFAULT_MAX_TIMEOUT, list_del, max, and ref_put.

Referenced by retry_poll().

◆ retry_poll()

void retry_poll ( void )

Poll the retry timer list.

Definition at line 198 of file retry.c.

198 {
199 struct retry_timer *timer;
200 unsigned long now = currticks();
201 unsigned long used;
202
203 /* Process at most one timer expiry. We cannot process
204 * multiple expiries in one pass, because one timer expiring
205 * may end up triggering another timer's deletion from the
206 * list.
207 */
208 list_for_each_entry ( timer, &timers, list ) {
209 used = ( now - timer->start );
210 if ( used >= timer->timeout ) {
212 break;
213 }
214 }
215}
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
static void timer_expired(struct retry_timer *timer)
Handle expired timer.
Definition retry.c:167
A retry timer.
Definition retry.h:22
struct list_head list
List of active timers.
Definition retry.h:24

References currticks(), retry_timer::list, list_for_each_entry, and timer_expired().

Referenced by eoib_poll(), ipoib_poll(), and retry_step().

◆ retry_step()

void retry_step ( struct process *process __unused)
static

Single-step the retry timer list.

Parameters
processRetry timer process

Definition at line 222 of file retry.c.

222 {
223 retry_poll();
224}
void retry_poll(void)
Poll the retry timer list.
Definition retry.c:198

References __unused, and retry_poll().

Referenced by PERMANENT_PROCESS().

◆ PERMANENT_PROCESS()

PERMANENT_PROCESS ( retry_process ,
retry_step  )

Retry timer process.

References retry_step().