OpenAFS
OpenAFS distributed network file system
|
00001 /* 00002 * Copyright 2000, International Business Machines Corporation and others. 00003 * All Rights Reserved. 00004 * 00005 * This software has been released under the terms of the IBM Public 00006 * License. For details, see the LICENSE file in the top-level source 00007 * directory or online at http://www.openafs.org/dl/license10.html 00008 */ 00009 00010 #ifndef OPENAFS_RX_CALL_H 00011 #define OPENAFS_RX_CALL_H 1 00012 00013 /* Call structure: only instantiated for active calls and dallying 00014 * server calls. The permanent call state (i.e. the call number as 00015 * well as state shared with other calls associated with this 00016 * connection) is maintained in the connection structure. */ 00017 00018 #ifdef KDUMP_RX_LOCK 00019 struct rx_call_rx_lock { 00020 #else 00021 struct rx_call { 00022 #endif 00023 struct rx_queue queue_item_header; /* Call can be on various queues (one-at-a-time) */ 00024 struct rx_queue tq; /* Transmit packet queue */ 00025 struct rx_queue rq; /* Receive packet queue */ 00026 /* 00027 * The following fields are accessed while the call is unlocked. 00028 * These fields are used by the caller/server thread to marshall 00029 * and unmarshall RPC data. The only time they may be changed by 00030 * other threads is when the RX_CALL_IOVEC_WAIT flag is set. 00031 * 00032 * NOTE: Be sure that these fields start and end on a double 00033 * word boundary. Otherwise threads that are changing 00034 * adjacent fields will cause problems. 00035 */ 00036 struct rx_queue iovq; /* readv/writev packet queue */ 00037 u_short nLeft; /* Number bytes left in first receive packet */ 00038 u_short curvec; /* current iovec in currentPacket */ 00039 u_short curlen; /* bytes remaining in curvec */ 00040 u_short nFree; /* Number bytes free in last send packet */ 00041 struct rx_packet *currentPacket; /* Current packet being assembled or being read */ 00042 char *curpos; /* current position in curvec */ 00043 /* 00044 * End of fields accessed with call unlocked 00045 */ 00046 u_char channel; /* Index of call, within connection */ 00047 u_char state; /* Current call state as defined below */ 00048 u_char mode; /* Current mode of a call in ACTIVE state */ 00049 #ifdef RX_ENABLE_LOCKS 00050 afs_kmutex_t lock; /* lock covers data as well as mutexes. */ 00051 afs_kmutex_t *call_queue_lock; /* points to lock for queue we're on, 00052 * if any. */ 00053 afs_kcondvar_t cv_twind; 00054 afs_kcondvar_t cv_rq; 00055 afs_kcondvar_t cv_tq; 00056 #endif 00057 #ifdef KDUMP_RX_LOCK 00058 struct rx_connection_rx_lock *conn; /* Parent connection for call */ 00059 #else 00060 struct rx_connection *conn; /* Parent connection for this call */ 00061 #endif 00062 afs_uint32 *callNumber; /* Pointer to call number field within connection */ 00063 afs_uint32 flags; /* Some random flags */ 00064 u_char localStatus; /* Local user status sent out of band */ 00065 u_char remoteStatus; /* Remote user status received out of band */ 00066 afs_int32 error; /* Error condition for this call */ 00067 afs_uint32 timeout; /* High level timeout for this call */ 00068 afs_uint32 rnext; /* Next sequence number expected to be read by rx_ReadData */ 00069 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 */ 00070 afs_uint32 rwind; /* The receive window: the peer must not send packets with sequence numbers >= rnext+rwind */ 00071 afs_uint32 tfirst; /* First unacknowledged transmit packet number */ 00072 afs_uint32 tnext; /* Next transmit sequence number to use */ 00073 afs_uint32 tprev; /* Last packet that we saw an ack for */ 00074 u_short twind; /* The transmit window: we cannot assign a sequence number to a packet >= tfirst + twind */ 00075 u_short cwind; /* The congestion window */ 00076 u_short nSoftAcked; /* Number soft acked transmit packets */ 00077 u_short nextCwind; /* The congestion window after recovery */ 00078 u_short nCwindAcks; /* Number acks received at current cwind */ 00079 u_short ssthresh; /* The slow start threshold */ 00080 u_short nDgramPackets; /* Packets per AFS 3.5 jumbogram */ 00081 u_short nAcks; /* The number of consecutive acks */ 00082 u_short nNacks; /* Number packets acked that follow the 00083 * first negatively acked packet */ 00084 u_short nSoftAcks; /* The number of delayed soft acks */ 00085 u_short nHardAcks; /* The number of delayed hard acks */ 00086 u_short congestSeq; /* Peer's congestion sequence counter */ 00087 int rtt; 00088 int rtt_dev; 00089 struct clock rto; /* The round trip timeout calculated for this call */ 00090 struct rxevent *resendEvent; /* If this is non-Null, there is a retransmission event pending */ 00091 struct rxevent *timeoutEvent; /* If this is non-Null, then there is an overall timeout for this call */ 00092 struct rxevent *keepAliveEvent; /* Scheduled periodically in active calls to keep call alive */ 00093 struct rxevent *growMTUEvent; /* Scheduled periodically in active calls to discover true maximum MTU */ 00094 struct rxevent *delayedAckEvent; /* Scheduled after all packets are received to send an ack if a reply or new call is not generated soon */ 00095 struct clock delayedAckTime; /* Time that next delayed ack was scheduled for */ 00096 struct rxevent *delayedAbortEvent; /* Scheduled to throttle looping client */ 00097 int abortCode; /* error code from last RPC */ 00098 int abortCount; /* number of times last error was sent */ 00099 u_int lastSendTime; /* Last time a packet was sent on this call */ 00100 u_int lastReceiveTime; /* Last time a packet was received for this call */ 00101 u_int lastSendData; /* Last time a nonping was sent on this call */ 00102 void (*arrivalProc) (struct rx_call * call, void * mh, int index); /* Procedure to call when reply is received */ 00103 void *arrivalProcHandle; /* Handle to pass to replyFunc */ 00104 int arrivalProcArg; /* Additional arg to pass to reply Proc */ 00105 afs_uint32 lastAcked; /* last packet "hard" acked by receiver */ 00106 afs_uint32 startWait; /* time server began waiting for input data/send quota */ 00107 struct clock traceWait; /* time server began waiting for input data/send quota */ 00108 struct clock traceStart; /* time the call started running */ 00109 u_short MTU; /* size of packets currently sending */ 00110 #ifdef RX_ENABLE_LOCKS 00111 short refCount; /* Used to keep calls from disappearring 00112 * when we get them from a queue. (rx_refcnt_lock) */ 00113 #endif /* RX_ENABLE_LOCKS */ 00114 /* Call refcount modifiers */ 00115 #define RX_CALL_REFCOUNT_BEGIN 0 /* GetCall/NewCall/EndCall */ 00116 #define RX_CALL_REFCOUNT_RESEND 1 /* resend event */ 00117 #define RX_CALL_REFCOUNT_DELAY 2 /* delayed ack */ 00118 #define RX_CALL_REFCOUNT_ALIVE 3 /* keep alive event */ 00119 #define RX_CALL_REFCOUNT_PACKET 4 /* waiting for packets. */ 00120 #define RX_CALL_REFCOUNT_SEND 5 /* rxi_Send */ 00121 #define RX_CALL_REFCOUNT_ABORT 7 /* delayed abort */ 00122 #define RX_CALL_REFCOUNT_MTU 8 /* grow mtu event */ 00123 #define RX_CALL_REFCOUNT_MAX 9 /* array size. */ 00124 #ifdef RX_REFCOUNT_CHECK 00125 short refCDebug[RX_CALL_REFCOUNT_MAX]; 00126 #endif /* RX_REFCOUNT_CHECK */ 00127 00128 /* 00129 * iov, iovNBytes, iovMax, and iovNext are set in rxi_ReadvProc() 00130 * and adjusted by rxi_FillReadVec(). iov does not own the buffers 00131 * it refers to. The buffers belong to the packets stored in iovq. 00132 * Only one call to rx_ReadvProc() can be active at a time. 00133 */ 00134 00135 int iovNBytes; /* byte count for current iovec */ 00136 int iovMax; /* number elements in current iovec */ 00137 int iovNext; /* next entry in current iovec */ 00138 struct iovec *iov; /* current iovec */ 00139 00140 struct clock queueTime; /* time call was queued */ 00141 struct clock startTime; /* time call was started */ 00142 afs_uint64 bytesSent; /* Number bytes sent */ 00143 afs_uint64 bytesRcvd; /* Number bytes received */ 00144 u_short tqWaiters; 00145 00146 struct rx_packet *xmitList[RX_MAXACKS]; /* Can't xmit more than we ack */ 00147 /* Protected by setting RX_CALL_TQ_BUSY */ 00148 #ifdef RXDEBUG_PACKET 00149 u_short tqc; /* packet count in tq */ 00150 u_short rqc; /* packet count in rq */ 00151 u_short iovqc; /* packet count in iovq */ 00152 00153 #ifdef KDUMP_RX_LOCK 00154 struct rx_call_rx_lock *allNextp; 00155 #else 00156 struct rx_call *allNextp; 00157 #endif 00158 afs_uint32 call_id; 00159 #endif 00160 #ifdef AFS_RXERRQ_ENV 00161 int neterr_gen; 00162 #endif 00163 }; 00164 00165 /* Only include this once, even when re-loading for kdump. */ 00166 #ifndef _CALL_REF_DEFINED_ 00167 #define _CALL_REF_DEFINED_ 00168 00169 #ifdef RX_ENABLE_LOCKS 00170 00171 # define CALL_HOLD(call, type) do { \ 00172 MUTEX_ENTER(&rx_refcnt_mutex); \ 00173 CALL_HOLD_R(call, type); \ 00174 MUTEX_EXIT(&rx_refcnt_mutex); \ 00175 } while(0) 00176 # define CALL_RELE(call, type) do { \ 00177 MUTEX_ENTER(&rx_refcnt_mutex); \ 00178 CALL_RELE_R(call, type); \ 00179 MUTEX_EXIT(&rx_refcnt_mutex); \ 00180 } while(0) 00181 00182 #ifdef RX_REFCOUNT_CHECK 00183 /* RX_REFCOUNT_CHECK is used to test for call refcount leaks by event 00184 * type. 00185 */ 00186 extern int rx_callHoldType; 00187 #define CALL_HOLD_R(call, type) do { \ 00188 call->refCount++; \ 00189 call->refCDebug[type]++; \ 00190 if (call->refCDebug[type] > 50) {\ 00191 rx_callHoldType = type; \ 00192 osi_Panic("Huge call refCount"); \ 00193 } \ 00194 } while (0) 00195 #define CALL_RELE_R(call, type) do { \ 00196 call->refCount--; \ 00197 call->refCDebug[type]--; \ 00198 if (call->refCDebug[type] > 50) {\ 00199 rx_callHoldType = type; \ 00200 osi_Panic("Negative call refCount"); \ 00201 } \ 00202 } while (0) 00203 #else /* RX_REFCOUNT_CHECK */ 00204 #define CALL_HOLD_R(call, type) call->refCount++ 00205 #define CALL_RELE_R(call, type) call->refCount-- 00206 #endif /* RX_REFCOUNT_CHECK */ 00207 00208 #else /* RX_ENABLE_LOCKS */ 00209 #define CALL_HOLD(call, type) 00210 #define CALL_RELE(call, type) 00211 #define CALL_RELE_R(call, type) 00212 #endif /* RX_ENABLE_LOCKS */ 00213 00214 #endif /* _CALL_REF_DEFINED_ */ 00215 00216 #endif