Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/cxgbe/tom/t4_cpl_io.c
Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
#include "common/common.h" | #include "common/common.h" | ||||
#include "common/t4_msg.h" | #include "common/t4_msg.h" | ||||
#include "common/t4_regs.h" | #include "common/t4_regs.h" | ||||
#include "common/t4_tcb.h" | #include "common/t4_tcb.h" | ||||
#include "tom/t4_tom_l2t.h" | #include "tom/t4_tom_l2t.h" | ||||
#include "tom/t4_tom.h" | #include "tom/t4_tom.h" | ||||
static void t4_aiotx_cancel(struct kaiocb *job); | static void t4_aiotx_cancel(struct kaiocb *job); | ||||
static void t4_aiotx_queue_toep(struct toepcb *toep); | static void t4_aiotx_queue_toep(struct socket *so, struct toepcb *toep); | ||||
static size_t | static size_t | ||||
aiotx_mbuf_pgoff(struct mbuf *m) | aiotx_mbuf_pgoff(struct mbuf *m) | ||||
{ | { | ||||
struct aiotx_buffer *ab; | struct aiotx_buffer *ab; | ||||
MPASS(IS_AIOTX_MBUF(m)); | MPASS(IS_AIOTX_MBUF(m)); | ||||
ab = m->m_ext.ext_arg1; | ab = m->m_ext.ext_arg1; | ||||
▲ Show 20 Lines • Show All 694 Lines • ▼ Show 20 Lines | for (m = sndptr; m != NULL; m = m->m_next) { | ||||
nsegs -= n; | nsegs -= n; | ||||
plen -= m->m_len; | plen -= m->m_len; | ||||
if (plen == 0) { | if (plen == 0) { | ||||
/* Too few credits */ | /* Too few credits */ | ||||
toep->flags |= TPF_TX_SUSPENDED; | toep->flags |= TPF_TX_SUSPENDED; | ||||
if (sowwakeup) { | if (sowwakeup) { | ||||
if (!TAILQ_EMPTY( | if (!TAILQ_EMPTY( | ||||
&toep->aiotx_jobq)) | &toep->aiotx_jobq)) | ||||
t4_aiotx_queue_toep( | t4_aiotx_queue_toep(so, | ||||
toep); | toep); | ||||
sowwakeup_locked(so); | sowwakeup_locked(so); | ||||
} else | } else | ||||
SOCKBUF_UNLOCK(sb); | SOCKBUF_UNLOCK(sb); | ||||
SOCKBUF_UNLOCK_ASSERT(sb); | SOCKBUF_UNLOCK_ASSERT(sb); | ||||
return; | return; | ||||
} | } | ||||
break; | break; | ||||
Show All 27 Lines | if (sb->sb_flags & SB_AUTOSIZE && | ||||
if (!sbreserve_locked(sb, newsize, so, NULL)) | if (!sbreserve_locked(sb, newsize, so, NULL)) | ||||
sb->sb_flags &= ~SB_AUTOSIZE; | sb->sb_flags &= ~SB_AUTOSIZE; | ||||
else | else | ||||
sowwakeup = 1; /* room available */ | sowwakeup = 1; /* room available */ | ||||
} | } | ||||
if (sowwakeup) { | if (sowwakeup) { | ||||
if (!TAILQ_EMPTY(&toep->aiotx_jobq)) | if (!TAILQ_EMPTY(&toep->aiotx_jobq)) | ||||
t4_aiotx_queue_toep(toep); | t4_aiotx_queue_toep(so, toep); | ||||
sowwakeup_locked(so); | sowwakeup_locked(so); | ||||
} else | } else | ||||
SOCKBUF_UNLOCK(sb); | SOCKBUF_UNLOCK(sb); | ||||
SOCKBUF_UNLOCK_ASSERT(sb); | SOCKBUF_UNLOCK_ASSERT(sb); | ||||
/* nothing to send */ | /* nothing to send */ | ||||
if (plen == 0) { | if (plen == 0) { | ||||
KASSERT(m == NULL, | KASSERT(m == NULL, | ||||
▲ Show 20 Lines • Show All 975 Lines • ▼ Show 20 Lines | #endif | ||||
sbdrop_locked(sb, plen); | sbdrop_locked(sb, plen); | ||||
if (tls_tx_key(toep)) { | if (tls_tx_key(toep)) { | ||||
struct tls_ofld_info *tls_ofld = &toep->tls; | struct tls_ofld_info *tls_ofld = &toep->tls; | ||||
MPASS(tls_ofld->sb_off >= plen); | MPASS(tls_ofld->sb_off >= plen); | ||||
tls_ofld->sb_off -= plen; | tls_ofld->sb_off -= plen; | ||||
} | } | ||||
if (!TAILQ_EMPTY(&toep->aiotx_jobq)) | if (!TAILQ_EMPTY(&toep->aiotx_jobq)) | ||||
t4_aiotx_queue_toep(toep); | t4_aiotx_queue_toep(so, toep); | ||||
sowwakeup_locked(so); /* unlocks so_snd */ | sowwakeup_locked(so); /* unlocks so_snd */ | ||||
} | } | ||||
SOCKBUF_UNLOCK_ASSERT(sb); | SOCKBUF_UNLOCK_ASSERT(sb); | ||||
} | } | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 357 Lines • ▼ Show 20 Lines | if (m != NULL) | ||||
m_free(m); | m_free(m); | ||||
SOCKBUF_LOCK(sb); | SOCKBUF_LOCK(sb); | ||||
} | } | ||||
static void | static void | ||||
t4_aiotx_task(void *context, int pending) | t4_aiotx_task(void *context, int pending) | ||||
{ | { | ||||
struct toepcb *toep = context; | struct toepcb *toep = context; | ||||
struct inpcb *inp = toep->inp; | struct socket *so; | ||||
struct socket *so = inp->inp_socket; | |||||
struct kaiocb *job; | struct kaiocb *job; | ||||
so = toep->aiotx_so; | |||||
CURVNET_SET(toep->vnet); | CURVNET_SET(toep->vnet); | ||||
SOCKBUF_LOCK(&so->so_snd); | SOCKBUF_LOCK(&so->so_snd); | ||||
while (!TAILQ_EMPTY(&toep->aiotx_jobq) && sowriteable(so)) { | while (!TAILQ_EMPTY(&toep->aiotx_jobq) && sowriteable(so)) { | ||||
job = TAILQ_FIRST(&toep->aiotx_jobq); | job = TAILQ_FIRST(&toep->aiotx_jobq); | ||||
TAILQ_REMOVE(&toep->aiotx_jobq, job, list); | TAILQ_REMOVE(&toep->aiotx_jobq, job, list); | ||||
if (!aio_clear_cancel_function(job)) | if (!aio_clear_cancel_function(job)) | ||||
continue; | continue; | ||||
t4_aiotx_process_job(toep, so, job); | t4_aiotx_process_job(toep, so, job); | ||||
} | } | ||||
toep->aiotx_task_active = false; | toep->aiotx_so = NULL; | ||||
SOCKBUF_UNLOCK(&so->so_snd); | SOCKBUF_UNLOCK(&so->so_snd); | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
free_toepcb(toep); | free_toepcb(toep); | ||||
SOCK_LOCK(so); | |||||
sorele(so); | |||||
} | } | ||||
static void | static void | ||||
t4_aiotx_queue_toep(struct toepcb *toep) | t4_aiotx_queue_toep(struct socket *so, struct toepcb *toep) | ||||
{ | { | ||||
SOCKBUF_LOCK_ASSERT(&toep->inp->inp_socket->so_snd); | SOCKBUF_LOCK_ASSERT(&toep->inp->inp_socket->so_snd); | ||||
#ifdef VERBOSE_TRACES | #ifdef VERBOSE_TRACES | ||||
CTR3(KTR_CXGBE, "%s: queueing aiotx task for tid %d, active = %s", | CTR3(KTR_CXGBE, "%s: queueing aiotx task for tid %d, active = %s", | ||||
__func__, toep->tid, toep->aiotx_task_active ? "true" : "false"); | __func__, toep->tid, toep->aiotx_task_active ? "true" : "false"); | ||||
#endif | #endif | ||||
if (toep->aiotx_task_active) | if (toep->aiotx_so != NULL) | ||||
return; | return; | ||||
toep->aiotx_task_active = true; | soref(so); | ||||
toep->aiotx_so = so; | |||||
hold_toepcb(toep); | hold_toepcb(toep); | ||||
soaio_enqueue(&toep->aiotx_task); | soaio_enqueue(&toep->aiotx_task); | ||||
} | } | ||||
static void | static void | ||||
t4_aiotx_cancel(struct kaiocb *job) | t4_aiotx_cancel(struct kaiocb *job) | ||||
{ | { | ||||
struct aiotx_buffer *ab; | struct aiotx_buffer *ab; | ||||
Show All 40 Lines | t4_aio_queue_aiotx(struct socket *so, struct kaiocb *job) | ||||
SOCKBUF_LOCK(&so->so_snd); | SOCKBUF_LOCK(&so->so_snd); | ||||
#ifdef VERBOSE_TRACES | #ifdef VERBOSE_TRACES | ||||
CTR2(KTR_CXGBE, "%s: queueing %p", __func__, job); | CTR2(KTR_CXGBE, "%s: queueing %p", __func__, job); | ||||
#endif | #endif | ||||
if (!aio_set_cancel_function(job, t4_aiotx_cancel)) | if (!aio_set_cancel_function(job, t4_aiotx_cancel)) | ||||
panic("new job was cancelled"); | panic("new job was cancelled"); | ||||
TAILQ_INSERT_TAIL(&toep->aiotx_jobq, job, list); | TAILQ_INSERT_TAIL(&toep->aiotx_jobq, job, list); | ||||
if (sowriteable(so)) | if (sowriteable(so)) | ||||
t4_aiotx_queue_toep(toep); | t4_aiotx_queue_toep(so, toep); | ||||
SOCKBUF_UNLOCK(&so->so_snd); | SOCKBUF_UNLOCK(&so->so_snd); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
aiotx_init_toep(struct toepcb *toep) | aiotx_init_toep(struct toepcb *toep) | ||||
{ | { | ||||
TAILQ_INIT(&toep->aiotx_jobq); | TAILQ_INIT(&toep->aiotx_jobq); | ||||
TASK_INIT(&toep->aiotx_task, 0, t4_aiotx_task, toep); | TASK_INIT(&toep->aiotx_task, 0, t4_aiotx_task, toep); | ||||
} | } | ||||
#endif | #endif |