rdsib_buf.c revision 8257fab973a69800a3a3309e8af21fc1876d2df9
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2005 SilverStorm Technologies, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
/*
* Sun elects to include this software in Sun product
* under the OpenIB BSD license.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This File contains the buffer management code
*/
#define DUMP_USER_PARAMS() \
static void
rds_free_mblk(char *arg)
{
/* Free the recv buffer */
}
void
{
int ret;
return;
}
/*
* All buffers must have been freed as all sessions are closed
* and destroyed
*/
while (rds_dpool.pool_nbusy != 0) {
}
if (ret == IBT_SUCCESS) {
} else {
"failed: %d, mrhdl: 0x%p", ret,
}
}
}
}
int
{
int ret;
"initialized");
return (0);
}
/* Max number of receive buffers on the system */
/*
* High water mark for the receive buffers in the system. If the
* number of buffers used crosses this mark then all sockets in
* would be stalled. The port quota for the sockets is set based
* on this limit.
*/
/* nsessions can never be less than 1 */
/* Add the hdr */
return (-1);
}
/* allocate memory for buffer entries */
KM_SLEEP);
/* register the memory with all HCAs */
if (ret != IBT_SUCCESS) {
return (-1);
}
}
/* Initialize data pool */
rds_dpool.pool_nbusy = 0;
/* chain the buffers */
}
/* Initialize ctrl pool */
rds_cpool.pool_nbusy = 0;
/* chain the buffers */
}
return (0);
}
void
{
int ret;
RDS_DPRINTF2("rds_free_send_pool",
"EP(%p) DOUBLE Free on Send Pool", ep);
return;
}
/* get the hcap for the HCA hosting this channel */
ep->ep_hca_guid);
} else {
if (ret != IBT_SUCCESS) {
"ibt_deregister_mr failed: %d, mrhdl: 0x%p",
}
if (ep->ep_ack_addr) {
if (ret != IBT_SUCCESS) {
"ibt_deregister_mr ackhdl failed: %d, "
}
}
}
}
int
{
int ret;
/* get the hcap for the HCA hosting this channel */
hca_guid);
return (-1);
}
spool->pool_nbusy = 0;
sizeof (uintptr_t);
} else {
spool->pool_nbusy = 0;
}
return (-1);
}
/* allocate memory for buffer entries */
KM_SLEEP);
/* register the memory with the HCA for this channel */
if (ret != IBT_SUCCESS) {
RDS_DPRINTF2("rds_init_send_pool",
"EP(%p): ibt_register_mr for ack failed: %d",
return (-1);
}
}
/* register the memory with the HCA for this channel */
if (ret != IBT_SUCCESS) {
return (-1);
}
/* Initialize the pool */
/* chain the buffers and initialize them */
}
} else {
/* control send pool */
}
}
return (0);
}
int
{
int ret;
/* deregister the send pool memory from the previous HCA */
ep->ep_hca_guid);
} else {
ep->ep_snd_mrhdl);
ep->ep_snd_lkey = 0;
}
ep->ep_ack_rkey = 0;
}
}
/* get the hcap for the new HCA */
hca_guid);
return (-1);
}
/* register the send memory */
if (ret != IBT_SUCCESS) {
RDS_DPRINTF2("rds_reinit_send_pool",
return (-1);
}
/* register the acknowledgement space */
if (ret != IBT_SUCCESS) {
RDS_DPRINTF2("rds_reinit_send_pool",
"EP(%p): ibt_register_mr for ack failed: %d",
ep->ep_snd_mrhdl);
ep->ep_snd_lkey = 0;
return (-1);
}
/* update the LKEY in the acknowledgement WR */
}
/* update the LKEY in each buffer */
while (bp) {
}
return (0);
}
void
{
} else {
}
}
}
int
{
rpool->pool_nbusy = 0;
rpool->pool_nfree = 0;
} else {
rpool->pool_nbusy = 0;
rpool->pool_nfree = 0;
}
return (0);
}
/* Free buffers to the global pool, either cpool or dpool */
void
{
if (pool->pool_nfree != 0) {
} else {
}
if (nbuf == 1) {
} else {
}
}
/* tail is always the last buffer */
}
/* Get buffers from the global pools, either cpool or dpool */
{
}
pool->pool_nfree = 0;
}
return (bp);
}
{
if (wait) {
/* wait until the RQ is empty */
/* wait one second and try again */
}
}
if (wait) {
/* Wait for all buffers to be freed by sockfs */
while (rpool->pool_nbusy != 0) {
/* wait one second and try again */
}
} else if (rpool->pool_nbusy != 0) {
}
return (ret);
}
{
/* check if all the sends completed */
if (wait) {
while (spool->pool_nbusy != 0) {
if (rds_no_interrupts) {
/* wait one second and try again */
B_TRUE);
} else {
/* wait one second and try again */
}
}
/*
* If the last one is acknowledged then everything
* is acknowledged
*/
"Checking for acknowledgements", ep);
RDS_DPRINTF2("rds_is_sendq_empty",
"EP(%p) BP(0x%p/0x%p) last "
}
}
} else if (spool->pool_nbusy != 0) {
}
/* check if all the rdma acks completed */
if (wait) {
while (ep->ep_rdmacnt != 0) {
if (rds_no_interrupts) {
/* wait one second and try again */
B_FALSE);
} else {
/* wait one second and try again */
}
}
} else if (ep->ep_rdmacnt != 0) {
}
return (ret1);
}
/* Get buffers from the send pool */
{
int ret;
if (rds_no_interrupts) {
(spool->pool_nbusy >
}
}
/* wait for buffers to become available */
/* ret = cv_wait_sig(&spool->pool_cv, &spool->pool_lock); */
if (ret == 0) {
/* signal pending */
return (NULL);
}
}
/* Have the number of buffers needed */
/* check if all the needed buffers are acknowledged */
/*
* The buffer is not yet signalled or
* is not yet acknowledged
*/
RDS_DPRINTF5("rds_get_send_buf",
"EP(%p) Buffer (%p) not yet "
return (NULL);
}
}
}
/* mark the buffers as pending */
}
}
return (bp);
}
#define RDS_MIN_BUF_TO_WAKE_THREADS 10
void
{
if (nbuf > 1) {
}
} else {
}
}
/* lock is not held outside */
}
if (spool->pool_nfree) {
} else {
}
if ((spool->pool_cv_count > 0) &&
else
}
}
}
#define RDS_NBUFFERS_TO_PUTBACK 100
void
{
/* Add the buffers to the local pool */
rpool->pool_nbusy--;
}
}
rpool->pool_nbusy--;
}
} else {
rpool->pool_nbusy--;
}
}
rpool->pool_nbusy--;
}
}
rpool->pool_nfree = 0;
/* Free the buffers to the global pool */
} else {
}
return;
}
}