o add a CRYPTO_F_CBIMM flag to symmetric ops to indicate the callback

should be done in crypto_done rather than in the callback thread
o use this flag to mark operations from /dev/crypto since the callback
  routine just does a wakeup; this eliminates the last unneeded ctx switch
o change CRYPTO_F_NODELAY to CRYPTO_F_BATCH with an inverted meaning
  so "0" becomes the default/desired setting (needed for user-mode
  compatibility with openbsd)
o change crypto_dispatch to honor CRYPTO_F_BATCH instead of always
  dispatching immediately
o remove uses of CRYPTO_F_NODELAY
o define COP_F_BATCH for ops submitted through /dev/crypto and pass
  this on to the op that is submitted

Similar changes and more eventually coming for asymmetric ops.

MFC if re gives approval.
This commit is contained in:
Sam Leffler 2003-02-23 07:25:48 +00:00
parent bdd64bca36
commit eb73a605cd
6 changed files with 81 additions and 32 deletions

View File

@ -687,7 +687,7 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
/* Crypto operation descriptor. */ /* Crypto operation descriptor. */
crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_NODELAY; crp->crp_flags = CRYPTO_F_IMBUF;
crp->crp_buf = (caddr_t) m; crp->crp_buf = (caddr_t) m;
crp->crp_callback = ah_input_cb; crp->crp_callback = ah_input_cb;
crp->crp_sid = sav->tdb_cryptoid; crp->crp_sid = sav->tdb_cryptoid;

View File

@ -395,7 +395,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
/* Crypto operation descriptor */ /* Crypto operation descriptor */
crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_NODELAY; crp->crp_flags = CRYPTO_F_IMBUF;
crp->crp_buf = (caddr_t) m; crp->crp_buf = (caddr_t) m;
crp->crp_callback = esp_input_cb; crp->crp_callback = esp_input_cb;
crp->crp_sid = sav->tdb_cryptoid; crp->crp_sid = sav->tdb_cryptoid;

View File

@ -173,7 +173,7 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
/* Crypto operation descriptor */ /* Crypto operation descriptor */
crp->crp_ilen = m->m_pkthdr.len - (skip + hlen); crp->crp_ilen = m->m_pkthdr.len - (skip + hlen);
crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_NODELAY; crp->crp_flags = CRYPTO_F_IMBUF;
crp->crp_buf = (caddr_t) m; crp->crp_buf = (caddr_t) m;
crp->crp_callback = ipcomp_input_cb; crp->crp_callback = ipcomp_input_cb;
crp->crp_sid = sav->tdb_cryptoid; crp->crp_sid = sav->tdb_cryptoid;

View File

@ -655,7 +655,6 @@ int
crypto_dispatch(struct cryptop *crp) crypto_dispatch(struct cryptop *crp)
{ {
u_int32_t hid = SESID2HID(crp->crp_sid); u_int32_t hid = SESID2HID(crp->crp_sid);
struct cryptocap *cap;
int result; int result;
cryptostats.cs_ops++; cryptostats.cs_ops++;
@ -665,29 +664,54 @@ crypto_dispatch(struct cryptop *crp)
binuptime(&crp->crp_tstamp); binuptime(&crp->crp_tstamp);
#endif #endif
CRYPTO_Q_LOCK(); if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
cap = crypto_checkdriver(hid); struct cryptocap *cap;
if (cap && !cap->cc_qblocked) { /*
result = crypto_invoke(crp, 0); * Caller marked the request to be processed
if (result == ERESTART) { * immediately; dispatch it directly to the
* driver unless the driver is currently blocked.
*/
cap = crypto_checkdriver(hid);
if (cap && !cap->cc_qblocked) {
result = crypto_invoke(crp, 0);
if (result == ERESTART) {
/*
* The driver ran out of resources, mark the
* driver ``blocked'' for cryptop's and put
* the request on the queue.
*/
CRYPTO_Q_LOCK();
crypto_drivers[hid].cc_qblocked = 1;
TAILQ_INSERT_HEAD(&crp_q, crp, crp_next);
CRYPTO_Q_UNLOCK();
cryptostats.cs_blocks++;
}
} else {
/* /*
* The driver ran out of resources, mark the * The driver is blocked, just queue the op until
* driver ``blocked'' for cryptop's and put * it unblocks and the kernel thread gets kicked.
* the request on the queue.
*/ */
crypto_drivers[hid].cc_qblocked = 1; CRYPTO_Q_LOCK();
TAILQ_INSERT_HEAD(&crp_q, crp, crp_next); TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
cryptostats.cs_blocks++; CRYPTO_Q_UNLOCK();
result = 0;
} }
} else { } else {
int wasempty;
/* /*
* The driver is blocked, just queue the op until * Caller marked the request as ``ok to delay'';
* it unblocks and the kernel thread gets kicked. * queue it for the dispatch thread. This is desirable
* when the operation is low priority and/or suitable
* for batching.
*/ */
CRYPTO_Q_LOCK();
wasempty = TAILQ_EMPTY(&crp_q);
TAILQ_INSERT_TAIL(&crp_q, crp, crp_next); TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
if (wasempty)
wakeup_one(&crp_q);
CRYPTO_Q_UNLOCK();
result = 0; result = 0;
} }
CRYPTO_Q_UNLOCK();
return result; return result;
} }
@ -818,8 +842,6 @@ crypto_invoke(struct cryptop *crp, int hint)
if (crypto_timing) if (crypto_timing)
crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp); crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
#endif #endif
mtx_assert(&crypto_q_mtx, MA_OWNED);
/* Sanity checks. */ /* Sanity checks. */
if (crp == NULL) if (crp == NULL)
return EINVAL; return EINVAL;
@ -917,21 +939,45 @@ crypto_getreq(int num)
void void
crypto_done(struct cryptop *crp) crypto_done(struct cryptop *crp)
{ {
int wasempty;
if (crp->crp_etype != 0) if (crp->crp_etype != 0)
cryptostats.cs_errs++; cryptostats.cs_errs++;
#ifdef CRYPTO_TIMING #ifdef CRYPTO_TIMING
if (crypto_timing) if (crypto_timing)
crypto_tstat(&cryptostats.cs_done, &crp->crp_tstamp); crypto_tstat(&cryptostats.cs_done, &crp->crp_tstamp);
#endif #endif
CRYPTO_RETQ_LOCK(); if (crp->crp_flags & CRYPTO_F_CBIMM) {
wasempty = TAILQ_EMPTY(&crp_ret_q); /*
TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next); * Do the callback directly. This is ok when the
* callback routine does very little (e.g. the
* /dev/crypto callback method just does a wakeup).
*/
#ifdef CRYPTO_TIMING
if (crypto_timing) {
/*
* NB: We must copy the timestamp before
* doing the callback as the cryptop is
* likely to be reclaimed.
*/
struct bintime t = crp->crp_tstamp;
crypto_tstat(&cryptostats.cs_cb, &t);
crp->crp_callback(crp);
crypto_tstat(&cryptostats.cs_finis, &t);
} else
#endif
crp->crp_callback(crp);
} else {
int wasempty;
/*
* Normal case; queue the callback for the thread.
*/
CRYPTO_RETQ_LOCK();
wasempty = TAILQ_EMPTY(&crp_ret_q);
TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
if (wasempty) if (wasempty)
wakeup_one(&crp_ret_q); /* shared wait channel */ wakeup_one(&crp_ret_q); /* shared wait channel */
CRYPTO_RETQ_UNLOCK(); CRYPTO_RETQ_UNLOCK();
}
} }
/* /*
@ -1043,7 +1089,7 @@ crypto_proc(void)
break; break;
} else { } else {
submit = crp; submit = crp;
if (submit->crp_flags & CRYPTO_F_NODELAY) if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
break; break;
/* keep scanning for more are q'd */ /* keep scanning for more are q'd */
} }

View File

@ -382,7 +382,8 @@ cryptodev_op(
} }
crp->crp_ilen = cop->len; crp->crp_ilen = cop->len;
crp->crp_flags = CRYPTO_F_IOV; crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
| (cop->flags & COP_F_BATCH);
crp->crp_buf = (caddr_t)&cse->uio; crp->crp_buf = (caddr_t)&cse->uio;
crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
crp->crp_sid = cse->sid; crp->crp_sid = cse->sid;

View File

@ -122,7 +122,8 @@ struct crypt_op {
u_int16_t op; /* i.e. COP_ENCRYPT */ u_int16_t op; /* i.e. COP_ENCRYPT */
#define COP_ENCRYPT 1 #define COP_ENCRYPT 1
#define COP_DECRYPT 2 #define COP_DECRYPT 2
u_int16_t flags; /* always 0 */ u_int16_t flags;
#define COP_F_BATCH 0x0008 /* Batch op if possible */
u_int len; u_int len;
caddr_t src, dst; /* become iov[] inside kernel */ caddr_t src, dst; /* become iov[] inside kernel */
caddr_t mac; /* must be big enough for chosen MAC */ caddr_t mac; /* must be big enough for chosen MAC */
@ -261,7 +262,8 @@ struct cryptop {
#define CRYPTO_F_IMBUF 0x0001 /* Input/output are mbuf chains, otherwise contig */ #define CRYPTO_F_IMBUF 0x0001 /* Input/output are mbuf chains, otherwise contig */
#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */ #define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
#define CRYPTO_F_REL 0x0004 /* Must return data in same place */ #define CRYPTO_F_REL 0x0004 /* Must return data in same place */
#define CRYPTO_F_NODELAY 0x0008 /* Dispatch as quickly as possible */ #define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
caddr_t crp_buf; /* Data to be processed */ caddr_t crp_buf; /* Data to be processed */
caddr_t crp_opaque; /* Opaque pointer, passed along */ caddr_t crp_opaque; /* Opaque pointer, passed along */