Deal with the case where a syncache entry added by the TOE driver is
evicted from the syncache but a later syncache_expand succeeds because of syncookies. The TOE driver has to resort to more direct means to install its hooks in the socket in this case.
This commit is contained in:
parent
b078416fae
commit
aac78a84d9
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/tcp_timer.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#define TCPSTATES
|
||||
#include <netinet/tcp_fsm.h>
|
||||
@ -759,6 +760,15 @@ do_pass_establish(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m)
|
||||
goto reset;
|
||||
}
|
||||
|
||||
if (__predict_false(!(synqe->flags & TP_SYNQE_EXPANDED))) {
|
||||
struct inpcb *new_inp = sotoinpcb(so);
|
||||
|
||||
INP_WLOCK(new_inp);
|
||||
tcp_timer_activate(intotcpcb(new_inp), TT_KEEP, 0);
|
||||
t3_offload_socket(tod, synqe, so);
|
||||
INP_WUNLOCK(new_inp);
|
||||
}
|
||||
|
||||
/* Remove the synq entry and release its reference on the lctx */
|
||||
TAILQ_REMOVE(&lctx->synq, synqe, link);
|
||||
inp = release_lctx(td, lctx);
|
||||
@ -1136,5 +1146,6 @@ t3_offload_socket(struct toedev *tod, void *arg, struct socket *so)
|
||||
offload_socket(so, toep);
|
||||
make_established(so, cpl->snd_isn, cpl->rcv_isn, cpl->tcp_opt);
|
||||
update_tid(td, toep, synqe->tid);
|
||||
synqe->flags |= TP_SYNQE_EXPANDED;
|
||||
}
|
||||
#endif
|
||||
|
@ -44,6 +44,7 @@
|
||||
#define TP_IS_A_SYNQ_ENTRY (1 << 9)
|
||||
#define TP_ABORT_RPL_SENT (1 << 10)
|
||||
#define TP_SEND_FIN (1 << 11)
|
||||
#define TP_SYNQE_EXPANDED (1 << 12)
|
||||
|
||||
struct toepcb {
|
||||
TAILQ_ENTRY(toepcb) link; /* toep_list */
|
||||
|
@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp_timer.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#define TCPSTATES
|
||||
#include <netinet/tcp_fsm.h>
|
||||
@ -805,6 +806,7 @@ t4_offload_socket(struct toedev *tod, void *arg, struct socket *so)
|
||||
make_established(toep, cpl->snd_isn, cpl->rcv_isn, cpl->tcp_opt);
|
||||
toep->flags |= TPF_CPL_PENDING;
|
||||
update_tid(sc, synqe->tid, toep);
|
||||
synqe->flags |= TPF_SYNQE_EXPANDED;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -1349,6 +1351,24 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss,
|
||||
goto reset;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is for the unlikely case where the syncache entry that we added
|
||||
* has been evicted from the syncache, but the syncache_expand above
|
||||
* works because of syncookies.
|
||||
*
|
||||
* XXX: we've held the tcbinfo lock throughout so there's no risk of
|
||||
* anyone accept'ing a connection before we've installed our hooks, but
|
||||
* this somewhat defeats the purpose of having a tod_offload_socket :-(
|
||||
*/
|
||||
if (__predict_false(!(synqe->flags & TPF_SYNQE_EXPANDED))) {
|
||||
struct inpcb *new_inp = sotoinpcb(so);
|
||||
|
||||
INP_WLOCK(new_inp);
|
||||
tcp_timer_activate(intotcpcb(new_inp), TT_KEEP, 0);
|
||||
t4_offload_socket(TOEDEV(ifp), synqe, so);
|
||||
INP_WUNLOCK(new_inp);
|
||||
}
|
||||
|
||||
/* Done with the synqe */
|
||||
TAILQ_REMOVE(&lctx->synq, synqe, link);
|
||||
inp = release_lctx(sc, lctx);
|
||||
|
@ -66,6 +66,7 @@ enum {
|
||||
TPF_SYNQE = (1 << 8), /* synq_entry, not really a toepcb */
|
||||
TPF_SYNQE_NEEDFREE = (1 << 9), /* synq_entry was malloc'd separately */
|
||||
TPF_SYNQE_TCPDDP = (1 << 10), /* ulp_mode TCPDDP in toepcb */
|
||||
TPF_SYNQE_EXPANDED = (1 << 11), /* toepcb ready, tid context updated */
|
||||
};
|
||||
|
||||
enum {
|
||||
|
Loading…
Reference in New Issue
Block a user