kcf_cbufcall.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* crypto_bufcall(9F) group of routines.
*/
#include <sys/taskq_impl.h>
/*
* All pending crypto bufcalls are put on a list. cbuf_list_lock
* protects changes to this list.
*
* The following locking order is maintained in the code - The
* global cbuf_list_lock followed by the individual lock
* in a crypto bufcall structure (kc_lock).
*/
static kcf_cbuf_elem_t *cbuf_list_head;
static kcf_cbuf_elem_t *cbuf_list_tail;
/*
* Allocate and return a handle to be used for crypto_bufcall().
* Can be called from user context only.
*/
crypto_bufcall_alloc(void)
{
return (cbufp);
}
/*
* Free the handle if possible. Returns CRYPTO_SUCCESS if the handle
* is freed. Else it returns CRYPTO_BUSY.
*
* The client should do a crypto_unbufcall() if it receives a
* CRYPTO_BUSY.
*
* Can be called both from user and interrupt context.
*/
int
{
return (CRYPTO_BUSY);
}
return (CRYPTO_SUCCESS);
}
/*
* Schedule func() to be called when queue space is available to
* submit a crypto request.
*
* Can be called both from user and interrupt context.
*/
int
{
return (CRYPTO_ARGUMENTS_BAD);
}
return (CRYPTO_BUSY);
}
if (cbuf_list_head == NULL) {
} else {
}
/*
* Signal the crypto_bufcall_service thread to start
* working on this crypto bufcall request.
*/
return (CRYPTO_SUCCESS);
}
/*
* Cancel a pending crypto bufcall request. If the bufcall
* is currently executing, we wait till it is complete.
*
* Can only be called from user context.
*/
int
{
else
else
/*
* crypto_bufcall_service thread is working
* on this element. We will wait for that
* thread to signal us when done.
*/
return (CRYPTO_SUCCESS);
}
return (CRYPTO_SUCCESS);
}
/*
* We sample the number of jobs. We do not hold the lock
* as it is not necessary to get the exact count.
*/
/*
* One queue space each for init, update, and final.
*/
#define GSWQ_MINFREE 3
/*
* Go through the list of crypto bufcalls and do the necessary
* callbacks.
*/
static void
kcf_run_cbufcalls(void)
{
int count;
/*
* Get estimate of available queue space from KCF_GSWQ_AVAIL.
* We can call 'n' crypto bufcall callback functions where
* n * GSWQ_MINFREE <= available queue space.
*
* TO DO - Extend the check to taskqs of hardware providers.
* For now, we handle only the software providers.
*/
if (GSWQ_MINFREE <= count) {
count -= GSWQ_MINFREE;
} else {
/*
* There is not enough queue space in this
* round. We bail out and try again
* later.
*/
break;
}
}
if (cbuf_list_head == NULL)
}
/*
* Background processing of crypto bufcalls.
*/
void
crypto_bufcall_service(void)
{
"crypto_bufcall_service");
for (;;) {
}
if (cbuf_list_head != NULL) {
/*
* Wait 30 seconds for queue space to become available.
* This number is reasonable as it does not cause
* much CPU overhead. We could wait on a condition
* variable and the global software dequeue routine can
* signal us. But, it adds overhead to that routine
* which we want to avoid. Also, the client is prepared
* to wait any way.
*/
}
/* Wait for new work to arrive */
if (cbuf_list_head == NULL) {
}
}
}