iPXE
Macros | Functions
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)
 
static LIST_HEAD (timers)
 List of running timers. More...
 
void start_timer_fixed (struct retry_timer *timer, unsigned long timeout)
 Start timer with a specified timeout. More...
 
void start_timer (struct retry_timer *timer)
 Start timer. More...
 
void stop_timer (struct retry_timer *timer)
 Stop timer. More...
 
static void timer_expired (struct retry_timer *timer)
 Handle expired timer. More...
 
void retry_poll (void)
 Poll the retry timer list. More...
 
static void retry_step (struct process *process __unused)
 Single-step the retry timer list. More...
 
 PERMANENT_PROCESS (retry_process, retry_step)
 Retry timer process. More...
 

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 49 of file retry.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ LIST_HEAD()

static 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 64 of file retry.c.

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

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

Referenced by 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(), http_transfer_complete(), ipair_rx_pair_error(), iphone_expired(), ipv6conf_expired(), 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(), 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 93 of file retry.c.

93  {
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 */
108 }
#define min(x, y)
Definition: ath.h:34
A timer.
Definition: timer.h:28
#define DEFAULT_MIN_TIMEOUT
Default minimum timeout value (in ticks)
Definition: retry.h:15
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
#define MIN_TIMEOUT
Definition: retry.c:49
void timeout(int)

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 117 of file retry.c.

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

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

Referenced by aoecmd_close(), dhcp_finished(), dhcp_set_state(), dhcpv6_finished(), dns_done(), dns_xfer_deliver(), 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(), http_close(), ib_destroy_madx(), ipair_close(), iphone_close(), ipv6conf_done(), ipv6conf_rx_router_advertisement(), neighbour_destroy(), neighbour_discovered(), 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(), 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()

static void timer_expired ( struct retry_timer timer)
static

Handle expired timer.

Parameters
timerRetry timer

Definition at line 166 of file retry.c.

166  {
167  struct refcnt *refcnt = timer->refcnt;
168  unsigned long max = ( timer->max ? timer->max : DEFAULT_MAX_TIMEOUT );
169  int fail;
170 
171  /* Stop timer without performing RTT calculations */
172  DBGC2 ( timer, "Timer %p stopped at time %ld on expiry\n",
173  timer, currticks() );
174  assert ( timer->running );
175  list_del ( &timer->list );
176  timer->running = 0;
177  timer->count++;
178 
179  /* Back off the timeout value */
180  timer->timeout <<= 1;
181  if ( ( fail = ( timer->timeout > max ) ) )
182  timer->timeout = max;
183  DBGC ( timer, "Timer %p timeout backed off to %ld\n",
184  timer, timer->timeout );
185 
186  /* Call expiry callback */
187  timer->expired ( timer, fail );
188  /* If refcnt is NULL, then timer may already have been freed */
189 
190  ref_put ( refcnt );
191 }
#define max(x, y)
Definition: ath.h:39
#define DBGC(...)
Definition: compiler.h:505
A reference counter.
Definition: refcnt.h:26
A timer.
Definition: timer.h:28
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define DEFAULT_MAX_TIMEOUT
Default maximum timeout value (in ticks)
Definition: retry.h:18
#define DBGC2(...)
Definition: compiler.h:522
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

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 197 of file retry.c.

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

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

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

◆ retry_step()

static void retry_step ( struct process *process  __unused)
static

Single-step the retry timer list.

Parameters
processRetry timer process

Definition at line 221 of file retry.c.

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

References retry_poll().

◆ PERMANENT_PROCESS()

PERMANENT_PROCESS ( retry_process  ,
retry_step   
)

Retry timer process.