2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #ifndef OPENAFS_RX_CALL_H
11 #define OPENAFS_RX_CALL_H 1
13 /* Call structure: only instantiated for active calls and dallying
14 * server calls. The permanent call state (i.e. the call number as
15 * well as state shared with other calls associated with this
16 * connection) is maintained in the connection structure. */
19 struct rx_call_rx_lock {
23 struct rx_queue queue_item_header; /* Call can be on various queues (one-at-a-time) */
24 struct rx_queue tq; /* Transmit packet queue */
25 struct rx_queue rq; /* Receive packet queue */
27 * The following fields are accessed while the call is unlocked.
28 * These fields are used by the caller/server thread to marshall
29 * and unmarshall RPC data. The only time they may be changed by
30 * other threads is when the RX_CALL_IOVEC_WAIT flag is set.
32 * NOTE: Be sure that these fields start and end on a double
33 * word boundary. Otherwise threads that are changing
34 * adjacent fields will cause problems.
36 struct rx_queue iovq; /* readv/writev packet queue */
37 u_short nLeft; /* Number bytes left in first receive packet */
38 u_short curvec; /* current iovec in currentPacket */
39 u_short curlen; /* bytes remaining in curvec */
40 u_short nFree; /* Number bytes free in last send packet */
41 struct rx_packet *currentPacket; /* Current packet being assembled or being read */
42 char *curpos; /* current position in curvec */
44 * End of fields accessed with call unlocked
46 u_char channel; /* Index of call, within connection */
47 u_char state; /* Current call state as defined below */
48 u_char mode; /* Current mode of a call in ACTIVE state */
49 #ifdef RX_ENABLE_LOCKS
50 afs_kmutex_t lock; /* lock covers data as well as mutexes. */
51 afs_kmutex_t *call_queue_lock; /* points to lock for queue we're on,
53 afs_kcondvar_t cv_twind;
58 struct rx_connection_rx_lock *conn; /* Parent connection for call */
60 struct rx_connection *conn; /* Parent connection for this call */
62 afs_uint32 *callNumber; /* Pointer to call number field within connection */
63 afs_uint32 flags; /* Some random flags */
64 u_char localStatus; /* Local user status sent out of band */
65 u_char remoteStatus; /* Remote user status received out of band */
66 afs_int32 error; /* Error condition for this call */
67 afs_uint32 timeout; /* High level timeout for this call */
68 afs_uint32 rnext; /* Next sequence number expected to be read by rx_ReadData */
69 afs_uint32 rprev; /* Previous packet received; used for deciding what the next packet to be received should be, in order to decide whether a negative acknowledge should be sent */
70 afs_uint32 rwind; /* The receive window: the peer must not send packets with sequence numbers >= rnext+rwind */
71 afs_uint32 tfirst; /* First unacknowledged transmit packet number */
72 afs_uint32 tnext; /* Next transmit sequence number to use */
73 afs_uint32 tprev; /* Last packet that we saw an ack for */
74 u_short twind; /* The transmit window: we cannot assign a sequence number to a packet >= tfirst + twind */
75 u_short cwind; /* The congestion window */
76 u_short nSoftAcked; /* Number soft acked transmit packets */
77 u_short nextCwind; /* The congestion window after recovery */
78 u_short nCwindAcks; /* Number acks received at current cwind */
79 u_short ssthresh; /* The slow start threshold */
80 u_short nDgramPackets; /* Packets per AFS 3.5 jumbogram */
81 u_short nAcks; /* The number of consecutive acks */
82 u_short nNacks; /* Number packets acked that follow the
83 * first negatively acked packet */
84 u_short nSoftAcks; /* The number of delayed soft acks */
85 u_short nHardAcks; /* The number of delayed hard acks */
86 u_short congestSeq; /* Peer's congestion sequence counter */
89 struct clock rto; /* The round trip timeout calculated for this call */
90 struct rxevent *resendEvent; /* If this is non-Null, there is a retransmission event pending */
91 struct rxevent *timeoutEvent; /* If this is non-Null, then there is an overall timeout for this call */
92 struct rxevent *keepAliveEvent; /* Scheduled periodically in active calls to keep call alive */
93 struct rxevent *growMTUEvent; /* Scheduled periodically in active calls to discover true maximum MTU */
94 struct rxevent *delayedAckEvent; /* Scheduled after all packets are received to send an ack if a reply or new call is not generated soon */
95 struct clock delayedAckTime; /* Time that next delayed ack was scheduled for */
96 struct rxevent *delayedAbortEvent; /* Scheduled to throttle looping client */
97 int abortCode; /* error code from last RPC */
98 int abortCount; /* number of times last error was sent */
99 u_int lastSendTime; /* Last time a packet was sent on this call */
100 u_int lastReceiveTime; /* Last time a packet was received for this call */
101 u_int lastSendData; /* Last time a nonping was sent on this call */
102 void (*arrivalProc) (struct rx_call * call, void * mh, int index); /* Procedure to call when reply is received */
103 void *arrivalProcHandle; /* Handle to pass to replyFunc */
104 int arrivalProcArg; /* Additional arg to pass to reply Proc */
105 afs_uint32 lastAcked; /* last packet "hard" acked by receiver */
106 afs_uint32 startWait; /* time server began waiting for input data/send quota */
107 struct clock traceWait; /* time server began waiting for input data/send quota */
108 struct clock traceStart; /* time the call started running */
109 u_short MTU; /* size of packets currently sending */
110 #ifdef RX_ENABLE_LOCKS
111 short refCount; /* Used to keep calls from disappearring
112 * when we get them from a queue. (rx_refcnt_lock) */
113 #endif /* RX_ENABLE_LOCKS */
114 /* Call refcount modifiers */
115 #define RX_CALL_REFCOUNT_BEGIN 0 /* GetCall/NewCall/EndCall */
116 #define RX_CALL_REFCOUNT_RESEND 1 /* resend event */
117 #define RX_CALL_REFCOUNT_DELAY 2 /* delayed ack */
118 #define RX_CALL_REFCOUNT_ALIVE 3 /* keep alive event */
119 #define RX_CALL_REFCOUNT_PACKET 4 /* waiting for packets. */
120 #define RX_CALL_REFCOUNT_SEND 5 /* rxi_Send */
121 #define RX_CALL_REFCOUNT_ABORT 7 /* delayed abort */
122 #define RX_CALL_REFCOUNT_MTU 8 /* grow mtu event */
123 #define RX_CALL_REFCOUNT_MAX 9 /* array size. */
124 #ifdef RX_REFCOUNT_CHECK
125 short refCDebug[RX_CALL_REFCOUNT_MAX];
126 #endif /* RX_REFCOUNT_CHECK */
129 * iov, iovNBytes, iovMax, and iovNext are set in rxi_ReadvProc()
130 * and adjusted by rxi_FillReadVec(). iov does not own the buffers
131 * it refers to. The buffers belong to the packets stored in iovq.
132 * Only one call to rx_ReadvProc() can be active at a time.
135 int iovNBytes; /* byte count for current iovec */
136 int iovMax; /* number elements in current iovec */
137 int iovNext; /* next entry in current iovec */
138 struct iovec *iov; /* current iovec */
140 struct clock queueTime; /* time call was queued */
141 struct clock startTime; /* time call was started */
142 afs_uint64 bytesSent; /* Number bytes sent */
143 afs_uint64 bytesRcvd; /* Number bytes received */
146 struct rx_packet *xmitList[RX_MAXACKS]; /* Can't xmit more than we ack */
147 /* Protected by setting RX_CALL_TQ_BUSY */
148 #ifdef RXDEBUG_PACKET
149 u_short tqc; /* packet count in tq */
150 u_short rqc; /* packet count in rq */
151 u_short iovqc; /* packet count in iovq */
154 struct rx_call_rx_lock *allNextp;
156 struct rx_call *allNextp;
160 #ifdef AFS_RXERRQ_ENV
165 /* Only include this once, even when re-loading for kdump. */
166 #ifndef _CALL_REF_DEFINED_
167 #define _CALL_REF_DEFINED_
169 #ifdef RX_ENABLE_LOCKS
171 # define CALL_HOLD(call, type) do { \
172 MUTEX_ENTER(&rx_refcnt_mutex); \
173 CALL_HOLD_R(call, type); \
174 MUTEX_EXIT(&rx_refcnt_mutex); \
176 # define CALL_RELE(call, type) do { \
177 MUTEX_ENTER(&rx_refcnt_mutex); \
178 CALL_RELE_R(call, type); \
179 MUTEX_EXIT(&rx_refcnt_mutex); \
182 #ifdef RX_REFCOUNT_CHECK
183 /* RX_REFCOUNT_CHECK is used to test for call refcount leaks by event
186 extern int rx_callHoldType;
187 #define CALL_HOLD_R(call, type) do { \
189 call->refCDebug[type]++; \
190 if (call->refCDebug[type] > 50) {\
191 rx_callHoldType = type; \
192 osi_Panic("Huge call refCount"); \
195 #define CALL_RELE_R(call, type) do { \
197 call->refCDebug[type]--; \
198 if (call->refCDebug[type] > 50) {\
199 rx_callHoldType = type; \
200 osi_Panic("Negative call refCount"); \
203 #else /* RX_REFCOUNT_CHECK */
204 #define CALL_HOLD_R(call, type) call->refCount++
205 #define CALL_RELE_R(call, type) call->refCount--
206 #endif /* RX_REFCOUNT_CHECK */
208 #else /* RX_ENABLE_LOCKS */
209 #define CALL_HOLD(call, type)
210 #define CALL_RELE(call, type)
211 #define CALL_RELE_R(call, type)
212 #endif /* RX_ENABLE_LOCKS */
214 #endif /* _CALL_REF_DEFINED_ */