19e39c5baSBill Taylor /*
29e39c5baSBill Taylor * CDDL HEADER START
39e39c5baSBill Taylor *
49e39c5baSBill Taylor * The contents of this file are subject to the terms of the
59e39c5baSBill Taylor * Common Development and Distribution License (the "License").
69e39c5baSBill Taylor * You may not use this file except in compliance with the License.
79e39c5baSBill Taylor *
89e39c5baSBill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e39c5baSBill Taylor * or http://www.opensolaris.org/os/licensing.
109e39c5baSBill Taylor * See the License for the specific language governing permissions
119e39c5baSBill Taylor * and limitations under the License.
129e39c5baSBill Taylor *
139e39c5baSBill Taylor * When distributing Covered Code, include this CDDL HEADER in each
149e39c5baSBill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e39c5baSBill Taylor * If applicable, add the following below this CDDL HEADER, with the
169e39c5baSBill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
179e39c5baSBill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
189e39c5baSBill Taylor *
199e39c5baSBill Taylor * CDDL HEADER END
209e39c5baSBill Taylor */
219e39c5baSBill Taylor
229e39c5baSBill Taylor /*
239e39c5baSBill Taylor * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
249e39c5baSBill Taylor */
259e39c5baSBill Taylor
269e39c5baSBill Taylor /*
279e39c5baSBill Taylor * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
289e39c5baSBill Taylor * Use is subject to license terms.
299e39c5baSBill Taylor */
309e39c5baSBill Taylor
319e39c5baSBill Taylor /*
329e39c5baSBill Taylor *
339e39c5baSBill Taylor * MODULE: dapl_evd_util.c
349e39c5baSBill Taylor *
359e39c5baSBill Taylor * PURPOSE: Manage EVD Info structure
369e39c5baSBill Taylor *
379e39c5baSBill Taylor * $Id: dapl_evd_util.c,v 1.41 2003/08/20 13:18:36 sjs2 Exp $
389e39c5baSBill Taylor */
399e39c5baSBill Taylor
409e39c5baSBill Taylor #include <sys/time.h>
419e39c5baSBill Taylor #include <strings.h>
429e39c5baSBill Taylor #include "dapl_evd_util.h"
439e39c5baSBill Taylor #include "dapl_ia_util.h"
449e39c5baSBill Taylor #include "dapl_cno_util.h"
459e39c5baSBill Taylor #include "dapl_ring_buffer_util.h"
469e39c5baSBill Taylor #include "dapl_adapter_util.h"
479e39c5baSBill Taylor #include "dapl_tavor_ibtf_impl.h"
489e39c5baSBill Taylor #include "dapl_cookie.h"
499e39c5baSBill Taylor #include "dapl.h"
509e39c5baSBill Taylor
519e39c5baSBill Taylor
529e39c5baSBill Taylor #ifdef DAPL_DBG /* For debugging. */
539e39c5baSBill Taylor static void
549e39c5baSBill Taylor dapli_evd_eh_print_cqe(
559e39c5baSBill Taylor IN ib_work_completion_t cqe);
569e39c5baSBill Taylor #endif
579e39c5baSBill Taylor
589e39c5baSBill Taylor static DAT_BOOLEAN
599e39c5baSBill Taylor dapli_evd_cqe_to_event(
609e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
619e39c5baSBill Taylor IN ib_work_completion_t *cqe_ptr,
629e39c5baSBill Taylor IN DAT_BOOLEAN process_premature_events,
639e39c5baSBill Taylor OUT DAT_EVENT *event_ptr);
649e39c5baSBill Taylor
659e39c5baSBill Taylor static DAT_RETURN
669e39c5baSBill Taylor dapli_evd_event_alloc(
679e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
689e39c5baSBill Taylor IN DAPL_CNO *cno_ptr,
699e39c5baSBill Taylor IN DAT_COUNT qlen);
709e39c5baSBill Taylor
719e39c5baSBill Taylor
729e39c5baSBill Taylor /*
739e39c5baSBill Taylor * dapls_evd_internal_create
749e39c5baSBill Taylor *
759e39c5baSBill Taylor * actually create the evd. this is called after all parameter checking
769e39c5baSBill Taylor * has been performed in dapl_ep_create. it is also called from dapl_ia_open
779e39c5baSBill Taylor * to create the default async evd.
789e39c5baSBill Taylor *
799e39c5baSBill Taylor * Input:
80*93fec3daSToomas Soome * ia_ptr
819e39c5baSBill Taylor * cno_ptr
829e39c5baSBill Taylor * qlen
839e39c5baSBill Taylor * evd_flags
849e39c5baSBill Taylor *
859e39c5baSBill Taylor * Output:
86*93fec3daSToomas Soome * evd_ptr_ptr
879e39c5baSBill Taylor *
889e39c5baSBill Taylor * Returns:
89*93fec3daSToomas Soome * none
909e39c5baSBill Taylor *
919e39c5baSBill Taylor */
929e39c5baSBill Taylor
939e39c5baSBill Taylor DAT_RETURN
dapls_evd_internal_create(DAPL_IA * ia_ptr,DAPL_CNO * cno_ptr,DAT_COUNT min_qlen,DAT_EVD_FLAGS evd_flags,DAPL_EVD ** evd_ptr_ptr)949e39c5baSBill Taylor dapls_evd_internal_create(
959e39c5baSBill Taylor DAPL_IA *ia_ptr,
969e39c5baSBill Taylor DAPL_CNO *cno_ptr,
979e39c5baSBill Taylor DAT_COUNT min_qlen,
989e39c5baSBill Taylor DAT_EVD_FLAGS evd_flags,
999e39c5baSBill Taylor DAPL_EVD **evd_ptr_ptr)
1009e39c5baSBill Taylor {
1019e39c5baSBill Taylor DAPL_EVD *evd_ptr;
1029e39c5baSBill Taylor DAT_COUNT cq_len;
1039e39c5baSBill Taylor DAT_RETURN dat_status;
1049e39c5baSBill Taylor
1059e39c5baSBill Taylor dat_status = DAT_SUCCESS;
1069e39c5baSBill Taylor *evd_ptr_ptr = NULL;
1079e39c5baSBill Taylor cq_len = min_qlen;
1089e39c5baSBill Taylor
1099e39c5baSBill Taylor evd_ptr = dapls_evd_alloc(ia_ptr,
1109e39c5baSBill Taylor cno_ptr,
1119e39c5baSBill Taylor evd_flags,
1129e39c5baSBill Taylor min_qlen);
1139e39c5baSBill Taylor if (!evd_ptr) {
1149e39c5baSBill Taylor dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
1159e39c5baSBill Taylor DAT_RESOURCE_MEMORY);
1169e39c5baSBill Taylor goto bail;
1179e39c5baSBill Taylor }
1189e39c5baSBill Taylor
1199e39c5baSBill Taylor /*
1209e39c5baSBill Taylor * If we are dealing with event streams besides a CQ event stream,
1219e39c5baSBill Taylor * be conservative and set producer side locking. Otherwise, no.
1229e39c5baSBill Taylor */
1239e39c5baSBill Taylor evd_ptr->evd_producer_locking_needed =
1249e39c5baSBill Taylor ((evd_flags & ~ (DAT_EVD_DTO_FLAG|DAT_EVD_RMR_BIND_FLAG)) != 0);
1259e39c5baSBill Taylor
1269e39c5baSBill Taylor /* Before we setup any callbacks, transition state to OPEN. */
1279e39c5baSBill Taylor evd_ptr->evd_state = DAPL_EVD_STATE_OPEN;
1289e39c5baSBill Taylor
1299e39c5baSBill Taylor /*
1309e39c5baSBill Taylor * we need to call cq_alloc even for connection/cr/async evds
1319e39c5baSBill Taylor * since all the allocation happens there.
1329e39c5baSBill Taylor */
1339e39c5baSBill Taylor dat_status = dapls_ib_cq_alloc(ia_ptr,
1349e39c5baSBill Taylor evd_ptr, cno_ptr, &cq_len);
1359e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
1369e39c5baSBill Taylor goto bail;
1379e39c5baSBill Taylor }
1389e39c5baSBill Taylor
139*93fec3daSToomas Soome #if 0
140*93fec3daSToomas Soome /*
141*93fec3daSToomas Soome * Current implementation of dapls_ib_setup_async_callback() does
142*93fec3daSToomas Soome * nothing and returns DAT_SUCCESS. However, it is declared to expect
143*93fec3daSToomas Soome * function pointers with different signatures. We do leave the code
144*93fec3daSToomas Soome * block out till dapls_ib_setup_async_callback() is implemented.
145*93fec3daSToomas Soome */
1469e39c5baSBill Taylor dat_status = dapls_ib_setup_async_callback(
1479e39c5baSBill Taylor ia_ptr,
1489e39c5baSBill Taylor DAPL_ASYNC_CQ_COMPLETION,
1499e39c5baSBill Taylor (unsigned int *) evd_ptr->ib_cq_handle,
1509e39c5baSBill Taylor (ib_async_handler_t)dapl_evd_dto_callback,
1519e39c5baSBill Taylor evd_ptr);
1529e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
1539e39c5baSBill Taylor goto bail;
1549e39c5baSBill Taylor }
155*93fec3daSToomas Soome #endif
1569e39c5baSBill Taylor /*
1579e39c5baSBill Taylor * cq_notify is not required since when evd_wait is called
1589e39c5baSBill Taylor * time we go and poll cq anyways.
1599e39c5baSBill Taylor * dat_status = dapls_set_cq_notify(ia_ptr, evd_ptr);
1609e39c5baSBill Taylor */
1619e39c5baSBill Taylor
1629e39c5baSBill Taylor /*
1639e39c5baSBill Taylor * We now have an accurate count of events, so allocate them into
1649e39c5baSBill Taylor * the EVD
1659e39c5baSBill Taylor */
1669e39c5baSBill Taylor dat_status = dapli_evd_event_alloc(evd_ptr, cno_ptr, cq_len);
1679e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
1689e39c5baSBill Taylor goto bail;
1699e39c5baSBill Taylor }
1709e39c5baSBill Taylor
1719e39c5baSBill Taylor /* We're assuming success in the following. */
1729e39c5baSBill Taylor dapl_os_assert(dat_status == DAT_SUCCESS);
1739e39c5baSBill Taylor dapl_ia_link_evd(ia_ptr, evd_ptr);
1749e39c5baSBill Taylor *evd_ptr_ptr = evd_ptr;
1759e39c5baSBill Taylor
1769e39c5baSBill Taylor bail:
1779e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
1789e39c5baSBill Taylor if (evd_ptr) {
1799e39c5baSBill Taylor (void) dapls_evd_dealloc(evd_ptr);
1809e39c5baSBill Taylor }
1819e39c5baSBill Taylor }
1829e39c5baSBill Taylor
1839e39c5baSBill Taylor return (dat_status);
1849e39c5baSBill Taylor }
1859e39c5baSBill Taylor
1869e39c5baSBill Taylor /*
1879e39c5baSBill Taylor * dapls_evd_alloc
1889e39c5baSBill Taylor *
1899e39c5baSBill Taylor * alloc and initialize an EVD struct
1909e39c5baSBill Taylor *
1919e39c5baSBill Taylor * Input:
192*93fec3daSToomas Soome * ia
1939e39c5baSBill Taylor *
1949e39c5baSBill Taylor * Output:
195*93fec3daSToomas Soome * evd_ptr
1969e39c5baSBill Taylor *
1979e39c5baSBill Taylor * Returns:
198*93fec3daSToomas Soome * none
1999e39c5baSBill Taylor *
2009e39c5baSBill Taylor */
2019e39c5baSBill Taylor DAPL_EVD *
dapls_evd_alloc(IN DAPL_IA * ia_ptr,IN DAPL_CNO * cno_ptr,IN DAT_EVD_FLAGS evd_flags,IN DAT_COUNT qlen)2029e39c5baSBill Taylor dapls_evd_alloc(
2039e39c5baSBill Taylor IN DAPL_IA *ia_ptr,
2049e39c5baSBill Taylor IN DAPL_CNO *cno_ptr,
2059e39c5baSBill Taylor IN DAT_EVD_FLAGS evd_flags,
2069e39c5baSBill Taylor IN DAT_COUNT qlen) /* ARGSUSED */
2079e39c5baSBill Taylor {
2089e39c5baSBill Taylor DAPL_EVD *evd_ptr;
2099e39c5baSBill Taylor
2109e39c5baSBill Taylor evd_ptr = NULL;
2119e39c5baSBill Taylor
2129e39c5baSBill Taylor /* Allocate EVD */
2139e39c5baSBill Taylor evd_ptr = (DAPL_EVD *)dapl_os_alloc(sizeof (DAPL_EVD));
2149e39c5baSBill Taylor if (!evd_ptr) {
2159e39c5baSBill Taylor goto bail;
2169e39c5baSBill Taylor }
2179e39c5baSBill Taylor
2189e39c5baSBill Taylor /* zero the structure */
2199e39c5baSBill Taylor (void) dapl_os_memzero(evd_ptr, sizeof (DAPL_EVD));
2209e39c5baSBill Taylor
2219e39c5baSBill Taylor /*
2229e39c5baSBill Taylor * initialize the header
2239e39c5baSBill Taylor */
2249e39c5baSBill Taylor evd_ptr->header.provider = ia_ptr->header.provider;
2259e39c5baSBill Taylor evd_ptr->header.magic = DAPL_MAGIC_EVD;
2269e39c5baSBill Taylor evd_ptr->header.handle_type = DAT_HANDLE_TYPE_EVD;
2279e39c5baSBill Taylor evd_ptr->header.owner_ia = ia_ptr;
2289e39c5baSBill Taylor evd_ptr->header.user_context.as_64 = 0;
2299e39c5baSBill Taylor evd_ptr->header.user_context.as_ptr = NULL;
2309e39c5baSBill Taylor dapl_llist_init_entry(&evd_ptr->header.ia_list_entry);
2319e39c5baSBill Taylor dapl_os_lock_init(&evd_ptr->header.lock);
2329e39c5baSBill Taylor
2339e39c5baSBill Taylor /*
2349e39c5baSBill Taylor * Initialize the body
2359e39c5baSBill Taylor */
2369e39c5baSBill Taylor evd_ptr->evd_state = DAPL_EVD_STATE_INITIAL;
2379e39c5baSBill Taylor evd_ptr->evd_flags = evd_flags;
2389e39c5baSBill Taylor evd_ptr->evd_enabled = DAT_TRUE;
2399e39c5baSBill Taylor evd_ptr->evd_waitable = DAT_TRUE;
2409e39c5baSBill Taylor evd_ptr->evd_producer_locking_needed = 1; /* Conservative value. */
2419e39c5baSBill Taylor evd_ptr->ib_cq_handle = IB_INVALID_HANDLE;
2429e39c5baSBill Taylor evd_ptr->evd_ref_count = 0;
2439e39c5baSBill Taylor evd_ptr->catastrophic_overflow = DAT_FALSE;
2449e39c5baSBill Taylor evd_ptr->qlen = qlen;
2459e39c5baSBill Taylor
2469e39c5baSBill Taylor dapl_llist_init_entry(&evd_ptr->cno_list_entry);
2479e39c5baSBill Taylor evd_ptr->completion_type = DAPL_EVD_STATE_THRESHOLD;
2489e39c5baSBill Taylor (void) dapl_os_wait_object_init(&evd_ptr->wait_object);
2499e39c5baSBill Taylor
2509e39c5baSBill Taylor bail:
2519e39c5baSBill Taylor return (evd_ptr);
2529e39c5baSBill Taylor }
2539e39c5baSBill Taylor
2549e39c5baSBill Taylor
2559e39c5baSBill Taylor /*
2569e39c5baSBill Taylor * dapls_evd_event_alloc
2579e39c5baSBill Taylor *
2589e39c5baSBill Taylor * alloc events into an EVD.
2599e39c5baSBill Taylor *
2609e39c5baSBill Taylor * Input:
261*93fec3daSToomas Soome * evd_ptr
2629e39c5baSBill Taylor * qlen
2639e39c5baSBill Taylor *
2649e39c5baSBill Taylor * Output:
265*93fec3daSToomas Soome * NONE
2669e39c5baSBill Taylor *
2679e39c5baSBill Taylor * Returns:
268*93fec3daSToomas Soome * DAT_SUCCESS
2699e39c5baSBill Taylor * ERROR
2709e39c5baSBill Taylor *
2719e39c5baSBill Taylor */
2729e39c5baSBill Taylor DAT_RETURN
dapli_evd_event_alloc(IN DAPL_EVD * evd_ptr,IN DAPL_CNO * cno_ptr,IN DAT_COUNT qlen)2739e39c5baSBill Taylor dapli_evd_event_alloc(
2749e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
2759e39c5baSBill Taylor IN DAPL_CNO *cno_ptr,
2769e39c5baSBill Taylor IN DAT_COUNT qlen)
2779e39c5baSBill Taylor {
2789e39c5baSBill Taylor DAT_EVENT *event_ptr;
2799e39c5baSBill Taylor DAT_COUNT i;
2809e39c5baSBill Taylor DAT_RETURN dat_status;
2819e39c5baSBill Taylor
2829e39c5baSBill Taylor dat_status = DAT_SUCCESS;
2839e39c5baSBill Taylor event_ptr = NULL;
2849e39c5baSBill Taylor
2859e39c5baSBill Taylor /* Allocate EVENTs */
2869e39c5baSBill Taylor event_ptr = (DAT_EVENT *) dapl_os_alloc(qlen * sizeof (DAT_EVENT));
2879e39c5baSBill Taylor if (!event_ptr) {
2889e39c5baSBill Taylor goto bail;
2899e39c5baSBill Taylor }
2909e39c5baSBill Taylor evd_ptr->events = event_ptr;
2919e39c5baSBill Taylor evd_ptr->qlen = qlen;
2929e39c5baSBill Taylor
2939e39c5baSBill Taylor /* allocate free event queue */
2949e39c5baSBill Taylor dat_status = dapls_rbuf_alloc(&evd_ptr->free_event_queue, qlen);
2959e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
2969e39c5baSBill Taylor goto bail;
2979e39c5baSBill Taylor }
2989e39c5baSBill Taylor
2999e39c5baSBill Taylor /* allocate pending event queue */
3009e39c5baSBill Taylor dat_status = dapls_rbuf_alloc(&evd_ptr->pending_event_queue, qlen);
3019e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
3029e39c5baSBill Taylor goto bail;
3039e39c5baSBill Taylor }
3049e39c5baSBill Taylor
3059e39c5baSBill Taylor /* add events to free event queue */
3069e39c5baSBill Taylor for (i = 0; i < qlen; i++) {
3079e39c5baSBill Taylor dat_status = dapls_rbuf_add(&evd_ptr->free_event_queue,
3089e39c5baSBill Taylor (void *)event_ptr);
3099e39c5baSBill Taylor dapl_os_assert(dat_status == DAT_SUCCESS);
3109e39c5baSBill Taylor event_ptr++;
3119e39c5baSBill Taylor }
3129e39c5baSBill Taylor evd_ptr->cq_notified = DAT_FALSE;
3139e39c5baSBill Taylor evd_ptr->cq_notified_when = 0;
3149e39c5baSBill Taylor evd_ptr->cno_active_count = 0;
3159e39c5baSBill Taylor if (cno_ptr != NULL) {
3169e39c5baSBill Taylor dapl_os_lock(&cno_ptr->header.lock);
3179e39c5baSBill Taylor dapl_llist_add_head(&cno_ptr->evd_list_head,
3189e39c5baSBill Taylor &evd_ptr->cno_list_entry, evd_ptr);
3199e39c5baSBill Taylor /* Take a reference count on the CNO */
3209e39c5baSBill Taylor dapl_os_atomic_inc(&cno_ptr->cno_ref_count);
3219e39c5baSBill Taylor dapl_os_unlock(&cno_ptr->header.lock);
3229e39c5baSBill Taylor }
3239e39c5baSBill Taylor evd_ptr->cno_ptr = cno_ptr;
3249e39c5baSBill Taylor evd_ptr->threshold = 0;
3259e39c5baSBill Taylor
3269e39c5baSBill Taylor bail:
3279e39c5baSBill Taylor return (dat_status);
3289e39c5baSBill Taylor }
3299e39c5baSBill Taylor
3309e39c5baSBill Taylor
3319e39c5baSBill Taylor /*
3329e39c5baSBill Taylor * dapls_evd_dealloc
3339e39c5baSBill Taylor *
3349e39c5baSBill Taylor * Free the passed in EVD structure. If an error occurs, this function
3359e39c5baSBill Taylor * will clean up all of the internal data structures and report the
3369e39c5baSBill Taylor * error.
3379e39c5baSBill Taylor *
3389e39c5baSBill Taylor * Input:
339*93fec3daSToomas Soome * evd_ptr
3409e39c5baSBill Taylor *
3419e39c5baSBill Taylor * Output:
342*93fec3daSToomas Soome * none
3439e39c5baSBill Taylor *
3449e39c5baSBill Taylor * Returns:
345*93fec3daSToomas Soome * status
3469e39c5baSBill Taylor *
3479e39c5baSBill Taylor */
3489e39c5baSBill Taylor DAT_RETURN
dapls_evd_dealloc(IN DAPL_EVD * evd_ptr)3499e39c5baSBill Taylor dapls_evd_dealloc(
3509e39c5baSBill Taylor IN DAPL_EVD *evd_ptr)
3519e39c5baSBill Taylor {
3529e39c5baSBill Taylor DAT_RETURN dat_status;
3539e39c5baSBill Taylor DAPL_IA *ia_ptr;
3549e39c5baSBill Taylor
3559e39c5baSBill Taylor dat_status = DAT_SUCCESS;
3569e39c5baSBill Taylor
3579e39c5baSBill Taylor dapl_os_assert(evd_ptr->header.magic == DAPL_MAGIC_EVD);
3589e39c5baSBill Taylor dapl_os_assert(evd_ptr->evd_ref_count == 0);
3599e39c5baSBill Taylor
3609e39c5baSBill Taylor /*
3619e39c5baSBill Taylor * Destroy the CQ first, to keep any more callbacks from coming
3629e39c5baSBill Taylor * up from it.
3639e39c5baSBill Taylor */
3649e39c5baSBill Taylor if (evd_ptr->ib_cq_handle != IB_INVALID_HANDLE) {
3659e39c5baSBill Taylor ia_ptr = evd_ptr->header.owner_ia;
3669e39c5baSBill Taylor
3679e39c5baSBill Taylor dat_status = dapls_ib_cq_free(ia_ptr, evd_ptr);
3689e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
3699e39c5baSBill Taylor goto bail;
3709e39c5baSBill Taylor }
3719e39c5baSBill Taylor }
3729e39c5baSBill Taylor
3739e39c5baSBill Taylor /*
3749e39c5baSBill Taylor * We should now be safe to invalidate the EVD; reset the
3759e39c5baSBill Taylor * magic to prevent reuse.
3769e39c5baSBill Taylor */
3779e39c5baSBill Taylor evd_ptr->header.magic = DAPL_MAGIC_INVALID;
3789e39c5baSBill Taylor
3799e39c5baSBill Taylor /* Release reference on the CNO if it exists */
3809e39c5baSBill Taylor if (evd_ptr->cno_ptr != NULL) {
3819e39c5baSBill Taylor dapl_os_lock(&evd_ptr->cno_ptr->header.lock);
3829e39c5baSBill Taylor (void) dapl_llist_remove_entry(&evd_ptr->cno_ptr->evd_list_head,
3839e39c5baSBill Taylor &evd_ptr->cno_list_entry);
3849e39c5baSBill Taylor dapl_os_atomic_dec(&evd_ptr->cno_ptr->cno_ref_count);
3859e39c5baSBill Taylor dapl_os_unlock(&evd_ptr->cno_ptr->header.lock);
3869e39c5baSBill Taylor }
3879e39c5baSBill Taylor
3889e39c5baSBill Taylor /*
3899e39c5baSBill Taylor * If the ring buffer allocation failed, then the dapls_rbuf_destroy
3909e39c5baSBill Taylor * function will detect that the ring buffer's internal data (ex. base
3919e39c5baSBill Taylor * pointer) are invalid and will handle the situation appropriately
3929e39c5baSBill Taylor */
3939e39c5baSBill Taylor dapls_rbuf_destroy(&evd_ptr->free_event_queue);
3949e39c5baSBill Taylor dapls_rbuf_destroy(&evd_ptr->pending_event_queue);
3959e39c5baSBill Taylor
3969e39c5baSBill Taylor if (evd_ptr->events) {
3979e39c5baSBill Taylor dapl_os_free(evd_ptr->events,
3989e39c5baSBill Taylor evd_ptr->qlen * sizeof (DAT_EVENT));
3999e39c5baSBill Taylor }
4009e39c5baSBill Taylor
4019e39c5baSBill Taylor (void) dapl_os_wait_object_destroy(&evd_ptr->wait_object);
4029e39c5baSBill Taylor dapl_os_free(evd_ptr, sizeof (DAPL_EVD));
4039e39c5baSBill Taylor
4049e39c5baSBill Taylor bail:
4059e39c5baSBill Taylor return (dat_status);
4069e39c5baSBill Taylor }
4079e39c5baSBill Taylor
4089e39c5baSBill Taylor
4099e39c5baSBill Taylor /*
4109e39c5baSBill Taylor * dapli_evd_eh_print_cqe
4119e39c5baSBill Taylor *
4129e39c5baSBill Taylor * Input:
4139e39c5baSBill Taylor * cqe
4149e39c5baSBill Taylor *
4159e39c5baSBill Taylor * Output:
4169e39c5baSBill Taylor * none
4179e39c5baSBill Taylor *
4189e39c5baSBill Taylor * Prints out a CQE for debug purposes
4199e39c5baSBill Taylor *
4209e39c5baSBill Taylor */
4219e39c5baSBill Taylor
4229e39c5baSBill Taylor #ifdef DAPL_DBG /* For debugging. */
4239e39c5baSBill Taylor void
dapli_evd_eh_print_cqe(IN ib_work_completion_t cqe)424*93fec3daSToomas Soome dapli_evd_eh_print_cqe(IN ib_work_completion_t cqe)
4259e39c5baSBill Taylor {
4269e39c5baSBill Taylor static char *optable[] = {
4279e39c5baSBill Taylor "",
4289e39c5baSBill Taylor "OP_SEND",
4299e39c5baSBill Taylor "OP_RDMA_READ",
4309e39c5baSBill Taylor "OP_RDMA_WRITE",
4319e39c5baSBill Taylor "OP_COMP_AND_SWAP",
4329e39c5baSBill Taylor "OP_FETCH_AND_ADD",
4339e39c5baSBill Taylor "OP_BIND_MW",
4349e39c5baSBill Taylor "OP_RECEIVE",
4359e39c5baSBill Taylor "OP_RECEIVE_RDMAWI",
4369e39c5baSBill Taylor 0
4379e39c5baSBill Taylor };
4389e39c5baSBill Taylor DAPL_COOKIE *dto_cookie;
4399e39c5baSBill Taylor
4409e39c5baSBill Taylor dto_cookie = (DAPL_COOKIE *) (uintptr_t)DAPL_GET_CQE_WRID(&cqe);
4419e39c5baSBill Taylor
4429e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
4439e39c5baSBill Taylor "\t >>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<\n");
4449e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
4459e39c5baSBill Taylor "\t dapl_evd_dto_callback : CQE \n");
4469e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
4479e39c5baSBill Taylor "\t\t work_req_id 0x%llx\n", DAPL_GET_CQE_WRID(&cqe));
4489e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
4499e39c5baSBill Taylor "\t\t op_type: %s\n", optable[DAPL_GET_CQE_OPTYPE(&cqe)]);
4509e39c5baSBill Taylor if ((DAPL_GET_CQE_OPTYPE(&cqe) == OP_SEND) ||
4519e39c5baSBill Taylor (DAPL_GET_CQE_OPTYPE(&cqe) == OP_RDMA_WRITE)) {
4529e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
4539e39c5baSBill Taylor "\t\t bytes_num %d\n", dto_cookie->val.dto.size);
4549e39c5baSBill Taylor } else {
4559e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
4569e39c5baSBill Taylor "\t\t bytes_num %d\n", DAPL_GET_CQE_BYTESNUM(&cqe));
4579e39c5baSBill Taylor }
4589e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
4599e39c5baSBill Taylor "\t\t status %d\n", DAPL_GET_CQE_STATUS(&cqe));
4609e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,
4619e39c5baSBill Taylor "\t >>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<\n");
4629e39c5baSBill Taylor }
4639e39c5baSBill Taylor #endif
4649e39c5baSBill Taylor
4659e39c5baSBill Taylor /*
4669e39c5baSBill Taylor * Event posting code follows.
4679e39c5baSBill Taylor */
4689e39c5baSBill Taylor
4699e39c5baSBill Taylor /*
4709e39c5baSBill Taylor * These next two functions (dapli_evd_get_event and dapli_evd_post_event)
4719e39c5baSBill Taylor * are a pair. They are always called together, from one of the functions
4729e39c5baSBill Taylor * at the end of this file (dapl_evd_post_*_event).
4739e39c5baSBill Taylor *
4749e39c5baSBill Taylor * Note that if producer side locking is enabled, the first one takes the
4759e39c5baSBill Taylor * EVD lock and the second releases it.
4769e39c5baSBill Taylor */
4779e39c5baSBill Taylor
4789e39c5baSBill Taylor /*
4799e39c5baSBill Taylor * dapli_evd_get_event
4809e39c5baSBill Taylor *
4819e39c5baSBill Taylor * Get an event struct from the evd. The caller should fill in the event
4829e39c5baSBill Taylor * and call dapl_evd_post_event.
4839e39c5baSBill Taylor *
4849e39c5baSBill Taylor * If there are no events available, an overflow event is generated to the
4859e39c5baSBill Taylor * async EVD handler.
4869e39c5baSBill Taylor *
4879e39c5baSBill Taylor * If this EVD required producer locking, a successful return implies
4889e39c5baSBill Taylor * that the lock is held.
4899e39c5baSBill Taylor *
4909e39c5baSBill Taylor * Input:
491*93fec3daSToomas Soome * evd_ptr
4929e39c5baSBill Taylor *
4939e39c5baSBill Taylor * Output:
4949e39c5baSBill Taylor * event
4959e39c5baSBill Taylor *
4969e39c5baSBill Taylor */
4979e39c5baSBill Taylor
4989e39c5baSBill Taylor static DAT_EVENT *
dapli_evd_get_event(DAPL_EVD * evd_ptr)4999e39c5baSBill Taylor dapli_evd_get_event(
5009e39c5baSBill Taylor DAPL_EVD *evd_ptr)
5019e39c5baSBill Taylor {
5029e39c5baSBill Taylor DAT_EVENT *event;
5039e39c5baSBill Taylor
5049e39c5baSBill Taylor if (evd_ptr->evd_producer_locking_needed) {
5059e39c5baSBill Taylor dapl_os_lock(&evd_ptr->header.lock);
5069e39c5baSBill Taylor }
5079e39c5baSBill Taylor
5089e39c5baSBill Taylor event = (DAT_EVENT *)dapls_rbuf_remove(&evd_ptr->free_event_queue);
5099e39c5baSBill Taylor
5109e39c5baSBill Taylor /* Release the lock if it was taken and the call failed. */
5119e39c5baSBill Taylor if (!event && evd_ptr->evd_producer_locking_needed) {
5129e39c5baSBill Taylor dapl_os_unlock(&evd_ptr->header.lock);
5139e39c5baSBill Taylor }
5149e39c5baSBill Taylor
5159e39c5baSBill Taylor return (event);
5169e39c5baSBill Taylor }
5179e39c5baSBill Taylor
5189e39c5baSBill Taylor /*
5199e39c5baSBill Taylor * dapli_evd_post_event
5209e39c5baSBill Taylor *
5219e39c5baSBill Taylor * Post the <event> to the evd. If possible, invoke the evd's CNO.
5229e39c5baSBill Taylor * Otherwise post the event on the pending queue.
5239e39c5baSBill Taylor *
5249e39c5baSBill Taylor * If producer side locking is required, the EVD lock must be held upon
5259e39c5baSBill Taylor * entry to this function.
5269e39c5baSBill Taylor *
5279e39c5baSBill Taylor * Input:
528*93fec3daSToomas Soome * evd_ptr
529*93fec3daSToomas Soome * event
5309e39c5baSBill Taylor *
5319e39c5baSBill Taylor * Output:
5329e39c5baSBill Taylor * none
5339e39c5baSBill Taylor *
5349e39c5baSBill Taylor */
5359e39c5baSBill Taylor
5369e39c5baSBill Taylor static void
dapli_evd_post_event(IN DAPL_EVD * evd_ptr,IN const DAT_EVENT * event_ptr)5379e39c5baSBill Taylor dapli_evd_post_event(
5389e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
5399e39c5baSBill Taylor IN const DAT_EVENT *event_ptr)
5409e39c5baSBill Taylor {
5419e39c5baSBill Taylor DAT_RETURN dat_status;
542*93fec3daSToomas Soome DAPL_CNO *cno_to_trigger = NULL;
5439e39c5baSBill Taylor
5449e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
5459e39c5baSBill Taylor "dapli_evd_post_event: Called with event # %x\n",
5469e39c5baSBill Taylor event_ptr->event_number);
5479e39c5baSBill Taylor
5489e39c5baSBill Taylor dat_status = dapls_rbuf_add(&evd_ptr->pending_event_queue,
5499e39c5baSBill Taylor (void *)event_ptr);
5509e39c5baSBill Taylor dapl_os_assert(dat_status == DAT_SUCCESS);
5519e39c5baSBill Taylor
5529e39c5baSBill Taylor dapl_os_assert(evd_ptr->evd_state == DAPL_EVD_STATE_WAITED ||
5539e39c5baSBill Taylor evd_ptr->evd_state == DAPL_EVD_STATE_OPEN);
5549e39c5baSBill Taylor
5559e39c5baSBill Taylor if (evd_ptr->evd_state == DAPL_EVD_STATE_OPEN) {
5569e39c5baSBill Taylor /* No waiter. Arrange to trigger a CNO if it exists. */
5579e39c5baSBill Taylor
5589e39c5baSBill Taylor if (evd_ptr->evd_enabled) {
5599e39c5baSBill Taylor cno_to_trigger = evd_ptr->cno_ptr;
5609e39c5baSBill Taylor }
5619e39c5baSBill Taylor if (evd_ptr->evd_producer_locking_needed) {
5629e39c5baSBill Taylor dapl_os_unlock(&evd_ptr->header.lock);
5639e39c5baSBill Taylor }
5649e39c5baSBill Taylor } else {
5659e39c5baSBill Taylor /*
5669e39c5baSBill Taylor * This routine gets called
5679e39c5baSBill Taylor * - In the context of the waiting thread when CQ, CM or ASYNC
5689e39c5baSBill Taylor * events need to be put on to the EVD ring buffer.
5699e39c5baSBill Taylor * - Due to a post of a software event.
5709e39c5baSBill Taylor *
5719e39c5baSBill Taylor * In the first case the waiting thread is pulling the events
5729e39c5baSBill Taylor * from various streams into the evd so there is no need to
5739e39c5baSBill Taylor * wake any thread. In the second case if the evd is in waited
5749e39c5baSBill Taylor * state then we need to wakeup the waiting thread.
5759e39c5baSBill Taylor */
5769e39c5baSBill Taylor if (event_ptr->event_number == DAT_SOFTWARE_EVENT) {
5779e39c5baSBill Taylor /*
5789e39c5baSBill Taylor * We're in DAPL_EVD_STATE_WAITED. Take the lock if
5799e39c5baSBill Taylor * we don't have it, recheck, and signal.
5809e39c5baSBill Taylor */
5819e39c5baSBill Taylor
5829e39c5baSBill Taylor if (!evd_ptr->evd_producer_locking_needed) {
5839e39c5baSBill Taylor dapl_os_lock(&evd_ptr->header.lock);
5849e39c5baSBill Taylor }
5859e39c5baSBill Taylor
5869e39c5baSBill Taylor if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED) {
5879e39c5baSBill Taylor dapl_os_unlock(&evd_ptr->header.lock);
5889e39c5baSBill Taylor (void) dapls_ib_event_wakeup(evd_ptr);
5899e39c5baSBill Taylor } else {
5909e39c5baSBill Taylor dapl_os_unlock(&evd_ptr->header.lock);
5919e39c5baSBill Taylor }
5929e39c5baSBill Taylor } else {
5939e39c5baSBill Taylor if (evd_ptr->evd_producer_locking_needed) {
5949e39c5baSBill Taylor dapl_os_unlock(&evd_ptr->header.lock);
5959e39c5baSBill Taylor }
5969e39c5baSBill Taylor }
5979e39c5baSBill Taylor }
5989e39c5baSBill Taylor
5999e39c5baSBill Taylor if (cno_to_trigger != NULL) {
6009e39c5baSBill Taylor dapl_cno_trigger(cno_to_trigger, evd_ptr);
6019e39c5baSBill Taylor }
6029e39c5baSBill Taylor }
6039e39c5baSBill Taylor
6049e39c5baSBill Taylor /*
6059e39c5baSBill Taylor * dapli_evd_post_event_nosignal
6069e39c5baSBill Taylor *
6079e39c5baSBill Taylor * Post the <event> to the evd. Do not do any wakeup processing.
6089e39c5baSBill Taylor * This function should only be called if it is known that there are
6099e39c5baSBill Taylor * no waiters that it is appropriate to wakeup on this EVD. An example
6109e39c5baSBill Taylor * of such a situation is during internal dat_evd_wait() processing.
6119e39c5baSBill Taylor *
6129e39c5baSBill Taylor * If producer side locking is required, the EVD lock must be held upon
6139e39c5baSBill Taylor * entry to this function.
6149e39c5baSBill Taylor *
6159e39c5baSBill Taylor * Input:
616*93fec3daSToomas Soome * evd_ptr
617*93fec3daSToomas Soome * event
6189e39c5baSBill Taylor *
6199e39c5baSBill Taylor * Output:
6209e39c5baSBill Taylor * none
6219e39c5baSBill Taylor *
6229e39c5baSBill Taylor */
6239e39c5baSBill Taylor
6249e39c5baSBill Taylor static void
dapli_evd_post_event_nosignal(IN DAPL_EVD * evd_ptr,IN const DAT_EVENT * event_ptr)6259e39c5baSBill Taylor dapli_evd_post_event_nosignal(
6269e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
6279e39c5baSBill Taylor IN const DAT_EVENT *event_ptr)
6289e39c5baSBill Taylor {
6299e39c5baSBill Taylor DAT_RETURN dat_status;
6309e39c5baSBill Taylor
6319e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
6329e39c5baSBill Taylor "dapli_evd_post_event: Called with event # %x\n",
6339e39c5baSBill Taylor event_ptr->event_number);
6349e39c5baSBill Taylor
6359e39c5baSBill Taylor dat_status = dapls_rbuf_add(&evd_ptr->pending_event_queue,
6369e39c5baSBill Taylor (void *)event_ptr);
6379e39c5baSBill Taylor dapl_os_assert(dat_status == DAT_SUCCESS);
6389e39c5baSBill Taylor
6399e39c5baSBill Taylor dapl_os_assert(evd_ptr->evd_state == DAPL_EVD_STATE_WAITED ||
6409e39c5baSBill Taylor evd_ptr->evd_state == DAPL_EVD_STATE_OPEN);
6419e39c5baSBill Taylor
6429e39c5baSBill Taylor if (evd_ptr->evd_producer_locking_needed) {
6439e39c5baSBill Taylor dapl_os_unlock(&evd_ptr->header.lock);
6449e39c5baSBill Taylor }
6459e39c5baSBill Taylor }
6469e39c5baSBill Taylor
6479e39c5baSBill Taylor /*
6489e39c5baSBill Taylor * dapli_evd_format_overflow_event
6499e39c5baSBill Taylor *
6509e39c5baSBill Taylor * format an overflow event for posting
6519e39c5baSBill Taylor *
6529e39c5baSBill Taylor * Input:
653*93fec3daSToomas Soome * evd_ptr
654*93fec3daSToomas Soome * event_ptr
6559e39c5baSBill Taylor *
6569e39c5baSBill Taylor * Output:
6579e39c5baSBill Taylor * none
6589e39c5baSBill Taylor *
6599e39c5baSBill Taylor */
6609e39c5baSBill Taylor static void
dapli_evd_format_overflow_event(IN DAPL_EVD * evd_ptr,OUT DAT_EVENT * event_ptr)6619e39c5baSBill Taylor dapli_evd_format_overflow_event(
6629e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
6639e39c5baSBill Taylor OUT DAT_EVENT *event_ptr)
6649e39c5baSBill Taylor {
6659e39c5baSBill Taylor DAPL_IA *ia_ptr;
6669e39c5baSBill Taylor
6679e39c5baSBill Taylor ia_ptr = evd_ptr->header.owner_ia;
6689e39c5baSBill Taylor
6699e39c5baSBill Taylor event_ptr->evd_handle = (DAT_EVD_HANDLE)evd_ptr;
6709e39c5baSBill Taylor event_ptr->event_number = DAT_ASYNC_ERROR_EVD_OVERFLOW;
6719e39c5baSBill Taylor event_ptr->event_data.asynch_error_event_data.dat_handle =
6729e39c5baSBill Taylor (DAT_HANDLE)ia_ptr;
6739e39c5baSBill Taylor }
6749e39c5baSBill Taylor
6759e39c5baSBill Taylor /*
6769e39c5baSBill Taylor * dapli_evd_post_overflow_event
6779e39c5baSBill Taylor *
6789e39c5baSBill Taylor * post an overflow event
6799e39c5baSBill Taylor *
6809e39c5baSBill Taylor * Input:
681*93fec3daSToomas Soome * async_evd_ptr
682*93fec3daSToomas Soome * evd_ptr
6839e39c5baSBill Taylor *
6849e39c5baSBill Taylor * Output:
6859e39c5baSBill Taylor * none
6869e39c5baSBill Taylor *
6879e39c5baSBill Taylor */
6889e39c5baSBill Taylor static void
dapli_evd_post_overflow_event(IN DAPL_EVD * async_evd_ptr,IN DAPL_EVD * overflow_evd_ptr)6899e39c5baSBill Taylor dapli_evd_post_overflow_event(
6909e39c5baSBill Taylor IN DAPL_EVD *async_evd_ptr,
6919e39c5baSBill Taylor IN DAPL_EVD *overflow_evd_ptr)
6929e39c5baSBill Taylor {
6939e39c5baSBill Taylor DAT_EVENT *overflow_event;
6949e39c5baSBill Taylor
6959e39c5baSBill Taylor /*
6969e39c5baSBill Taylor * The overflow_evd_ptr mght be the same as evd.
6979e39c5baSBill Taylor * In that case we've got a catastrophic overflow.
6989e39c5baSBill Taylor */
6999e39c5baSBill Taylor if (async_evd_ptr == overflow_evd_ptr) {
7009e39c5baSBill Taylor async_evd_ptr->catastrophic_overflow = DAT_TRUE;
7019e39c5baSBill Taylor async_evd_ptr->evd_state = DAPL_EVD_STATE_DEAD;
7029e39c5baSBill Taylor return;
7039e39c5baSBill Taylor }
7049e39c5baSBill Taylor
7059e39c5baSBill Taylor overflow_event = dapli_evd_get_event(overflow_evd_ptr);
7069e39c5baSBill Taylor if (!overflow_event) {
7079e39c5baSBill Taylor /* this is not good */
7089e39c5baSBill Taylor overflow_evd_ptr->catastrophic_overflow = DAT_TRUE;
7099e39c5baSBill Taylor overflow_evd_ptr->evd_state = DAPL_EVD_STATE_DEAD;
7109e39c5baSBill Taylor return;
7119e39c5baSBill Taylor }
7129e39c5baSBill Taylor dapli_evd_format_overflow_event(overflow_evd_ptr, overflow_event);
7139e39c5baSBill Taylor dapli_evd_post_event(overflow_evd_ptr, overflow_event);
7149e39c5baSBill Taylor }
7159e39c5baSBill Taylor
7169e39c5baSBill Taylor static DAT_EVENT *
dapli_evd_get_and_init_event(IN DAPL_EVD * evd_ptr,IN DAT_EVENT_NUMBER event_number)7179e39c5baSBill Taylor dapli_evd_get_and_init_event(
7189e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
7199e39c5baSBill Taylor IN DAT_EVENT_NUMBER event_number)
7209e39c5baSBill Taylor {
721*93fec3daSToomas Soome DAT_EVENT *event_ptr;
7229e39c5baSBill Taylor
7239e39c5baSBill Taylor event_ptr = dapli_evd_get_event(evd_ptr);
7249e39c5baSBill Taylor if (NULL == event_ptr) {
7259e39c5baSBill Taylor dapli_evd_post_overflow_event(
7269e39c5baSBill Taylor evd_ptr->header.owner_ia->async_error_evd, evd_ptr);
7279e39c5baSBill Taylor } else {
7289e39c5baSBill Taylor event_ptr->evd_handle = (DAT_EVD_HANDLE) evd_ptr;
7299e39c5baSBill Taylor event_ptr->event_number = event_number;
7309e39c5baSBill Taylor }
7319e39c5baSBill Taylor
7329e39c5baSBill Taylor return (event_ptr);
7339e39c5baSBill Taylor }
7349e39c5baSBill Taylor
7359e39c5baSBill Taylor DAT_RETURN
dapls_evd_post_cr_arrival_event(IN DAPL_EVD * evd_ptr,IN DAT_EVENT_NUMBER event_number,IN DAT_SP_HANDLE sp_handle,DAT_IA_ADDRESS_PTR ia_address_ptr,DAT_CONN_QUAL conn_qual,DAT_CR_HANDLE cr_handle)7369e39c5baSBill Taylor dapls_evd_post_cr_arrival_event(
7379e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
7389e39c5baSBill Taylor IN DAT_EVENT_NUMBER event_number,
7399e39c5baSBill Taylor IN DAT_SP_HANDLE sp_handle,
7409e39c5baSBill Taylor DAT_IA_ADDRESS_PTR ia_address_ptr,
7419e39c5baSBill Taylor DAT_CONN_QUAL conn_qual,
7429e39c5baSBill Taylor DAT_CR_HANDLE cr_handle)
7439e39c5baSBill Taylor {
744*93fec3daSToomas Soome DAT_EVENT *event_ptr;
7459e39c5baSBill Taylor event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
7469e39c5baSBill Taylor /*
7479e39c5baSBill Taylor * Note event lock may be held on successful return
7489e39c5baSBill Taylor * to be released by dapli_evd_post_event(), if provider side locking
7499e39c5baSBill Taylor * is needed.
7509e39c5baSBill Taylor */
7519e39c5baSBill Taylor
7529e39c5baSBill Taylor if (!event_ptr) {
7539e39c5baSBill Taylor return (DAT_INSUFFICIENT_RESOURCES | DAT_RESOURCE_MEMORY);
7549e39c5baSBill Taylor }
7559e39c5baSBill Taylor
7569e39c5baSBill Taylor event_ptr->event_data.cr_arrival_event_data.sp_handle = sp_handle;
7579e39c5baSBill Taylor event_ptr->event_data.cr_arrival_event_data.local_ia_address_ptr
7589e39c5baSBill Taylor = ia_address_ptr;
7599e39c5baSBill Taylor event_ptr->event_data.cr_arrival_event_data.conn_qual = conn_qual;
7609e39c5baSBill Taylor event_ptr->event_data.cr_arrival_event_data.cr_handle = cr_handle;
7619e39c5baSBill Taylor
7629e39c5baSBill Taylor dapli_evd_post_event(evd_ptr, event_ptr);
7639e39c5baSBill Taylor return (DAT_SUCCESS);
7649e39c5baSBill Taylor }
7659e39c5baSBill Taylor
7669e39c5baSBill Taylor
7679e39c5baSBill Taylor DAT_RETURN
dapls_evd_post_connection_event(IN DAPL_EVD * evd_ptr,IN DAT_EVENT_NUMBER event_number,IN DAT_EP_HANDLE ep_handle,IN DAT_COUNT private_data_size,IN DAT_PVOID private_data)7689e39c5baSBill Taylor dapls_evd_post_connection_event(
7699e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
7709e39c5baSBill Taylor IN DAT_EVENT_NUMBER event_number,
7719e39c5baSBill Taylor IN DAT_EP_HANDLE ep_handle,
7729e39c5baSBill Taylor IN DAT_COUNT private_data_size,
7739e39c5baSBill Taylor IN DAT_PVOID private_data)
7749e39c5baSBill Taylor {
775*93fec3daSToomas Soome DAT_EVENT *event_ptr;
7769e39c5baSBill Taylor event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
7779e39c5baSBill Taylor /*
7789e39c5baSBill Taylor * Note event lock may be held on successful return
7799e39c5baSBill Taylor * to be released by dapli_evd_post_event(), if provider side locking
7809e39c5baSBill Taylor * is needed.
7819e39c5baSBill Taylor */
7829e39c5baSBill Taylor
7839e39c5baSBill Taylor if (!event_ptr) {
7849e39c5baSBill Taylor return (DAT_INSUFFICIENT_RESOURCES | DAT_RESOURCE_MEMORY);
7859e39c5baSBill Taylor }
7869e39c5baSBill Taylor
7879e39c5baSBill Taylor event_ptr->event_data.connect_event_data.ep_handle = ep_handle;
7889e39c5baSBill Taylor event_ptr->event_data.connect_event_data.private_data_size
7899e39c5baSBill Taylor = private_data_size;
7909e39c5baSBill Taylor event_ptr->event_data.connect_event_data.private_data = private_data;
7919e39c5baSBill Taylor
7929e39c5baSBill Taylor dapli_evd_post_event(evd_ptr, event_ptr);
7939e39c5baSBill Taylor return (DAT_SUCCESS);
7949e39c5baSBill Taylor }
7959e39c5baSBill Taylor
7969e39c5baSBill Taylor
7979e39c5baSBill Taylor DAT_RETURN
dapls_evd_post_async_error_event(IN DAPL_EVD * evd_ptr,IN DAT_EVENT_NUMBER event_number,IN DAT_IA_HANDLE ia_handle)7989e39c5baSBill Taylor dapls_evd_post_async_error_event(
7999e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
8009e39c5baSBill Taylor IN DAT_EVENT_NUMBER event_number,
8019e39c5baSBill Taylor IN DAT_IA_HANDLE ia_handle)
8029e39c5baSBill Taylor {
803*93fec3daSToomas Soome DAT_EVENT *event_ptr;
8049e39c5baSBill Taylor event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
8059e39c5baSBill Taylor /*
8069e39c5baSBill Taylor * Note event lock may be held on successful return
8079e39c5baSBill Taylor * to be released by dapli_evd_post_event(), if provider side locking
8089e39c5baSBill Taylor * is needed.
8099e39c5baSBill Taylor */
8109e39c5baSBill Taylor
8119e39c5baSBill Taylor if (!event_ptr) {
8129e39c5baSBill Taylor return (DAT_INSUFFICIENT_RESOURCES | DAT_RESOURCE_MEMORY);
8139e39c5baSBill Taylor }
8149e39c5baSBill Taylor
8159e39c5baSBill Taylor event_ptr->event_data.asynch_error_event_data.dat_handle = ia_handle;
8169e39c5baSBill Taylor
8179e39c5baSBill Taylor dapli_evd_post_event(evd_ptr, event_ptr);
8189e39c5baSBill Taylor return (DAT_SUCCESS);
8199e39c5baSBill Taylor }
8209e39c5baSBill Taylor
8219e39c5baSBill Taylor
8229e39c5baSBill Taylor DAT_RETURN
dapls_evd_post_software_event(IN DAPL_EVD * evd_ptr,IN DAT_EVENT_NUMBER event_number,IN DAT_PVOID pointer)8239e39c5baSBill Taylor dapls_evd_post_software_event(
8249e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
8259e39c5baSBill Taylor IN DAT_EVENT_NUMBER event_number,
8269e39c5baSBill Taylor IN DAT_PVOID pointer)
8279e39c5baSBill Taylor {
828*93fec3daSToomas Soome DAT_EVENT *event_ptr;
8299e39c5baSBill Taylor event_ptr = dapli_evd_get_and_init_event(evd_ptr, event_number);
8309e39c5baSBill Taylor /*
8319e39c5baSBill Taylor * Note event lock may be held on successful return
8329e39c5baSBill Taylor * to be released by dapli_evd_post_event(), if provider side locking
8339e39c5baSBill Taylor * is needed.
8349e39c5baSBill Taylor */
8359e39c5baSBill Taylor
8369e39c5baSBill Taylor if (!event_ptr) {
8379e39c5baSBill Taylor return (DAT_QUEUE_FULL);
8389e39c5baSBill Taylor }
8399e39c5baSBill Taylor
8409e39c5baSBill Taylor event_ptr->event_data.software_event_data.pointer = pointer;
8419e39c5baSBill Taylor
8429e39c5baSBill Taylor dapli_evd_post_event(evd_ptr, event_ptr);
8439e39c5baSBill Taylor return (DAT_SUCCESS);
8449e39c5baSBill Taylor }
8459e39c5baSBill Taylor
8469e39c5baSBill Taylor void
dapls_evd_post_premature_events(IN DAPL_EP * ep_ptr)8479e39c5baSBill Taylor dapls_evd_post_premature_events(IN DAPL_EP *ep_ptr)
8489e39c5baSBill Taylor {
8499e39c5baSBill Taylor DAPL_EVD *evd_ptr;
8509e39c5baSBill Taylor DAT_EVENT *event;
8519e39c5baSBill Taylor ib_work_completion_t *cqe;
8529e39c5baSBill Taylor uint32_t qpn;
8539e39c5baSBill Taylor int prm_idx;
8549e39c5baSBill Taylor int nevents;
8559e39c5baSBill Taylor int i;
8569e39c5baSBill Taylor
8579e39c5baSBill Taylor dapls_ib_poll_premature_events(ep_ptr, &cqe, &nevents);
8589e39c5baSBill Taylor /* premature events are always recv events */
8599e39c5baSBill Taylor evd_ptr = ep_ptr->param.recv_evd_handle;
8609e39c5baSBill Taylor qpn = ep_ptr->qpn;
8619e39c5baSBill Taylor
8629e39c5baSBill Taylor i = 0;
8639e39c5baSBill Taylor prm_idx = 0;
8649e39c5baSBill Taylor while (i < nevents) {
8659e39c5baSBill Taylor /*
8669e39c5baSBill Taylor * If srq_attached, premature events cannot exceed max_recv_dtos
8679e39c5baSBill Taylor */
8689e39c5baSBill Taylor dapl_os_assert(!ep_ptr->srq_attached ||
8699e39c5baSBill Taylor (prm_idx <= ((DAPL_SRQ *)ep_ptr->param.srq_handle)->
8709e39c5baSBill Taylor param.max_recv_dtos));
8719e39c5baSBill Taylor
8729e39c5baSBill Taylor /*
8739e39c5baSBill Taylor * The SRQ premature event list could potentially have
8749e39c5baSBill Taylor * holes (ie. free entries in the middle) or premature
8759e39c5baSBill Taylor * events for other QPs. These need to be skipped.
8769e39c5baSBill Taylor */
8779e39c5baSBill Taylor if (ep_ptr->srq_attached &&
8789e39c5baSBill Taylor (!DAPL_CQE_IS_VALID(&cqe[prm_idx]) ||
8799e39c5baSBill Taylor (DAPL_GET_CQE_QPN(&cqe[prm_idx]) != qpn))) {
8809e39c5baSBill Taylor prm_idx++;
8819e39c5baSBill Taylor continue;
8829e39c5baSBill Taylor }
8839e39c5baSBill Taylor
8849e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,
8859e39c5baSBill Taylor " Premature DTO processing\n");
8869e39c5baSBill Taylor
8879e39c5baSBill Taylor #ifdef DAPL_DBG /* For debugging. */
8889e39c5baSBill Taylor dapli_evd_eh_print_cqe(cqe[i]);
8899e39c5baSBill Taylor #endif
8909e39c5baSBill Taylor /*
8919e39c5baSBill Taylor * Can use DAT_DTO_COMPLETION_EVENT because
8929e39c5baSBill Taylor * dapli_evd_cqe_to_event will overwrite.
8939e39c5baSBill Taylor */
8949e39c5baSBill Taylor event = dapli_evd_get_and_init_event(evd_ptr,
8959e39c5baSBill Taylor DAT_DTO_COMPLETION_EVENT);
8969e39c5baSBill Taylor if (event == NULL) {
8979e39c5baSBill Taylor /* We've already attempted the overflow post, return */
8989e39c5baSBill Taylor return;
8999e39c5baSBill Taylor }
9009e39c5baSBill Taylor (void) dapli_evd_cqe_to_event(evd_ptr, &cqe[i], DAT_TRUE,
9019e39c5baSBill Taylor event);
9029e39c5baSBill Taylor dapli_evd_post_event_nosignal(evd_ptr, event);
9039e39c5baSBill Taylor /*
9049e39c5baSBill Taylor * For SRQ attached QPs recycle the premature event
9059e39c5baSBill Taylor */
9069e39c5baSBill Taylor if (ep_ptr->srq_attached) {
9079e39c5baSBill Taylor dapls_ib_free_premature_events(ep_ptr, prm_idx);
9089e39c5baSBill Taylor prm_idx++;
9099e39c5baSBill Taylor }
9109e39c5baSBill Taylor i++;
9119e39c5baSBill Taylor }
9129e39c5baSBill Taylor }
9139e39c5baSBill Taylor
9149e39c5baSBill Taylor /*
9159e39c5baSBill Taylor * dapli_evd_cqe_to_event
9169e39c5baSBill Taylor *
9179e39c5baSBill Taylor * Convert a CQE into an event structure.
9189e39c5baSBill Taylor *
9199e39c5baSBill Taylor * Input:
9209e39c5baSBill Taylor * evd_ptr
921*93fec3daSToomas Soome * cqe_ptr
9229e39c5baSBill Taylor *
9239e39c5baSBill Taylor * Output:
924*93fec3daSToomas Soome * event_ptr
9259e39c5baSBill Taylor *
9269e39c5baSBill Taylor * Returns:
927*93fec3daSToomas Soome * none
9289e39c5baSBill Taylor *
9299e39c5baSBill Taylor */
9309e39c5baSBill Taylor static DAT_BOOLEAN
dapli_evd_cqe_to_event(IN DAPL_EVD * evd_ptr,IN ib_work_completion_t * cqe_ptr,IN DAT_BOOLEAN process_premature_events,OUT DAT_EVENT * event_ptr)9319e39c5baSBill Taylor dapli_evd_cqe_to_event(
9329e39c5baSBill Taylor IN DAPL_EVD *evd_ptr,
9339e39c5baSBill Taylor IN ib_work_completion_t *cqe_ptr,
9349e39c5baSBill Taylor IN DAT_BOOLEAN process_premature_events,
9359e39c5baSBill Taylor OUT DAT_EVENT *event_ptr)
9369e39c5baSBill Taylor {
9379e39c5baSBill Taylor DAPL_EP *ep_ptr;
9389e39c5baSBill Taylor DAPL_SRQ *srq_ptr;
9399e39c5baSBill Taylor DAPL_COOKIE *cookie;
9409e39c5baSBill Taylor DAT_EP_STATE ep_state;
9419e39c5baSBill Taylor ib_qp_handle_t qp;
9429e39c5baSBill Taylor ib_uint32_t ib_status;
9439e39c5baSBill Taylor ib_uint32_t ibtype;
9449e39c5baSBill Taylor int srq_enabled;
9459e39c5baSBill Taylor int dto_error = 0;
9469e39c5baSBill Taylor
9479e39c5baSBill Taylor
9489e39c5baSBill Taylor /*
9499e39c5baSBill Taylor * All that can be relied on if the status is bad is the status
9509e39c5baSBill Taylor * and WRID.
9519e39c5baSBill Taylor */
9529e39c5baSBill Taylor ib_status = DAPL_GET_CQE_STATUS(cqe_ptr);
9539e39c5baSBill Taylor
9549e39c5baSBill Taylor cookie = (DAPL_COOKIE *)((uintptr_t)DAPL_GET_CQE_WRID(cqe_ptr));
9559e39c5baSBill Taylor dapl_os_assert((NULL != cookie));
9569e39c5baSBill Taylor
9579e39c5baSBill Taylor if (cookie->queue_type == DAPL_COOKIE_QUEUE_EP) {
9589e39c5baSBill Taylor srq_enabled = 0;
9599e39c5baSBill Taylor ep_ptr = cookie->queue.ep;
9609e39c5baSBill Taylor } else {
9619e39c5baSBill Taylor srq_enabled = 1;
9629e39c5baSBill Taylor srq_ptr = cookie->queue.srq;
9639e39c5baSBill Taylor dapl_os_assert(NULL != srq_ptr);
9649e39c5baSBill Taylor dapl_os_assert(srq_ptr->header.magic == DAPL_MAGIC_SRQ);
9659e39c5baSBill Taylor ib_status = DAPL_GET_CQE_STATUS(cqe_ptr);
9669e39c5baSBill Taylor ep_ptr = dapls_ib_srq_lookup_ep(srq_ptr, cqe_ptr);
9679e39c5baSBill Taylor }
9689e39c5baSBill Taylor
9699e39c5baSBill Taylor dapl_os_assert((NULL != ep_ptr));
9709e39c5baSBill Taylor dapl_os_assert((ep_ptr->header.magic == DAPL_MAGIC_EP) ||
9719e39c5baSBill Taylor (ep_ptr->header.magic == DAPL_MAGIC_EP_EXIT));
9729e39c5baSBill Taylor
9739e39c5baSBill Taylor event_ptr->evd_handle = (DAT_EVD_HANDLE) evd_ptr;
9749e39c5baSBill Taylor
9759e39c5baSBill Taylor /*
9769e39c5baSBill Taylor * Check if the DTO completion arrived before CONNECTION_ESTABLISHED
9779e39c5baSBill Taylor * event -
9789e39c5baSBill Taylor *
9799e39c5baSBill Taylor * Send DTOs can occur only if ep state is CONNECTED/DISCONNECTED
9809e39c5baSBill Taylor * therefore it cannot occur before connection established event.
9819e39c5baSBill Taylor * Receive DTO can potentially complete before connection established
9829e39c5baSBill Taylor * event has been delivered to the client. In this case if the
9839e39c5baSBill Taylor * ep state is ACTIVE_CONNECTION_PENDING (active side) or
9849e39c5baSBill Taylor * COMPLETION_PENDING (passive side) the event is put in a special
9859e39c5baSBill Taylor * event queue in the qp_handle.
9869e39c5baSBill Taylor *
9879e39c5baSBill Taylor */
9889e39c5baSBill Taylor if (!process_premature_events &&
9899e39c5baSBill Taylor (cookie->type == DAPL_COOKIE_TYPE_DTO) &&
9909e39c5baSBill Taylor (ib_status == IB_COMP_ST_SUCCESS)) {
9919e39c5baSBill Taylor ep_state = ep_ptr->param.ep_state;
9929e39c5baSBill Taylor qp = ep_ptr->qp_handle;
9939e39c5baSBill Taylor if ((ep_state == DAT_EP_STATE_ACTIVE_CONNECTION_PENDING) ||
9949e39c5baSBill Taylor (ep_state == DAT_EP_STATE_COMPLETION_PENDING) ||
9959e39c5baSBill Taylor (qp->qp_num_premature_events > 0)) {
9969e39c5baSBill Taylor /*
9979e39c5baSBill Taylor * not yet ready to put the event in the evd ring
9989e39c5baSBill Taylor * buffer
9999e39c5baSBill Taylor */
10009e39c5baSBill Taylor dapls_ib_store_premature_events(qp, cqe_ptr);
10019e39c5baSBill Taylor return (DAT_FALSE);
10029e39c5baSBill Taylor }
10039e39c5baSBill Taylor }
10049e39c5baSBill Taylor
10059e39c5baSBill Taylor switch (cookie->type) {
10069e39c5baSBill Taylor case DAPL_COOKIE_TYPE_DTO:
10079e39c5baSBill Taylor {
10089e39c5baSBill Taylor DAPL_COOKIE_BUFFER *buffer;
10099e39c5baSBill Taylor
10109e39c5baSBill Taylor if (DAPL_DTO_TYPE_RECV == cookie->val.dto.type) {
10119e39c5baSBill Taylor if (srq_enabled) {
10129e39c5baSBill Taylor dapl_os_atomic_dec(&srq_ptr->recv_count);
10139e39c5baSBill Taylor buffer = &srq_ptr->recv_buffer;
10149e39c5baSBill Taylor } else {
10159e39c5baSBill Taylor dapl_os_atomic_dec(&ep_ptr->recv_count);
10169e39c5baSBill Taylor buffer = &ep_ptr->recv_buffer;
10179e39c5baSBill Taylor }
10189e39c5baSBill Taylor } else {
10199e39c5baSBill Taylor dapl_os_atomic_dec(&ep_ptr->req_count);
10209e39c5baSBill Taylor buffer = &ep_ptr->req_buffer;
10219e39c5baSBill Taylor }
10229e39c5baSBill Taylor
10239e39c5baSBill Taylor event_ptr->event_number = DAT_DTO_COMPLETION_EVENT;
10249e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.ep_handle =
10259e39c5baSBill Taylor ep_ptr;
10269e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.user_cookie =
10279e39c5baSBill Taylor cookie->val.dto.cookie;
10289e39c5baSBill Taylor
10299e39c5baSBill Taylor switch (ib_status) {
10309e39c5baSBill Taylor case IB_COMP_ST_SUCCESS:
10319e39c5baSBill Taylor {
10329e39c5baSBill Taylor ibtype = DAPL_GET_CQE_OPTYPE(cqe_ptr);
10339e39c5baSBill Taylor
10349e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10359e39c5baSBill Taylor DAT_DTO_SUCCESS;
10369e39c5baSBill Taylor dapl_os_assert((ibtype == OP_SEND &&
10379e39c5baSBill Taylor cookie->val.dto.type == DAPL_DTO_TYPE_SEND) ||
10389e39c5baSBill Taylor (ibtype == OP_RECEIVE &&
10399e39c5baSBill Taylor cookie->val.dto.type == DAPL_DTO_TYPE_RECV) ||
10409e39c5baSBill Taylor (ibtype == OP_RDMA_WRITE &&
10419e39c5baSBill Taylor cookie->val.dto.type ==
10429e39c5baSBill Taylor DAPL_DTO_TYPE_RDMA_WRITE) ||
10439e39c5baSBill Taylor (ibtype == OP_RDMA_READ &&
10449e39c5baSBill Taylor cookie->val.dto.type ==
10459e39c5baSBill Taylor DAPL_DTO_TYPE_RDMA_READ));
10469e39c5baSBill Taylor break;
10479e39c5baSBill Taylor }
10489e39c5baSBill Taylor case IB_COMP_ST_LOCAL_LEN_ERR:
10499e39c5baSBill Taylor {
10509e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10519e39c5baSBill Taylor DAT_DTO_ERR_LOCAL_LENGTH;
10529e39c5baSBill Taylor break;
10539e39c5baSBill Taylor }
10549e39c5baSBill Taylor case IB_COMP_ST_LOCAL_PROTECT_ERR:
10559e39c5baSBill Taylor {
10569e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10579e39c5baSBill Taylor DAT_DTO_ERR_LOCAL_PROTECTION;
10589e39c5baSBill Taylor break;
10599e39c5baSBill Taylor }
10609e39c5baSBill Taylor case IB_COMP_ST_WR_FLUSHED_ERR:
10619e39c5baSBill Taylor {
10629e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10639e39c5baSBill Taylor DAT_DTO_ERR_FLUSHED;
10649e39c5baSBill Taylor break;
10659e39c5baSBill Taylor }
10669e39c5baSBill Taylor case IB_COMP_ST_BAD_RESPONSE_ERR:
10679e39c5baSBill Taylor {
10689e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10699e39c5baSBill Taylor DAT_DTO_ERR_BAD_RESPONSE;
10709e39c5baSBill Taylor break;
10719e39c5baSBill Taylor }
10729e39c5baSBill Taylor case IB_COMP_ST_REM_REQ_ERR:
10739e39c5baSBill Taylor case IB_COMP_ST_REM_OP_ERR:
10749e39c5baSBill Taylor {
10759e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10769e39c5baSBill Taylor DAT_DTO_ERR_REMOTE_RESPONDER;
10779e39c5baSBill Taylor break;
10789e39c5baSBill Taylor }
10799e39c5baSBill Taylor case IB_COMP_ST_REM_ACC_ERR:
10809e39c5baSBill Taylor {
10819e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10829e39c5baSBill Taylor DAT_DTO_ERR_REMOTE_ACCESS;
10839e39c5baSBill Taylor break;
10849e39c5baSBill Taylor }
10859e39c5baSBill Taylor /*
10869e39c5baSBill Taylor * Unsupported RD errors
10879e39c5baSBill Taylor * case IB_COMP_ST_EE_STATE_ERR:
10889e39c5baSBill Taylor * case IB_COMP_ST_EE_CTX_NO_ERR:
10899e39c5baSBill Taylor */
10909e39c5baSBill Taylor case IB_COMP_ST_TRANSP_COUNTER:
10919e39c5baSBill Taylor {
10929e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10939e39c5baSBill Taylor DAT_DTO_ERR_TRANSPORT;
10949e39c5baSBill Taylor break;
10959e39c5baSBill Taylor }
10969e39c5baSBill Taylor case IB_COMP_ST_RNR_COUNTER:
10979e39c5baSBill Taylor {
10989e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
10999e39c5baSBill Taylor DAT_DTO_ERR_RECEIVER_NOT_READY;
11009e39c5baSBill Taylor break;
11019e39c5baSBill Taylor }
11029e39c5baSBill Taylor case IB_COMP_ST_MW_BIND_ERR:
11039e39c5baSBill Taylor {
11049e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
11059e39c5baSBill Taylor DAT_RMR_OPERATION_FAILED;
11069e39c5baSBill Taylor break;
11079e39c5baSBill Taylor }
11089e39c5baSBill Taylor case IB_COMP_ST_LOCAL_OP_ERR:
11099e39c5baSBill Taylor {
11109e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
11119e39c5baSBill Taylor DAT_DTO_ERR_LOCAL_EP;
11129e39c5baSBill Taylor break;
11139e39c5baSBill Taylor }
11149e39c5baSBill Taylor default:
11159e39c5baSBill Taylor {
11169e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,
11179e39c5baSBill Taylor " DTO completion ERROR: %d: op %#x\n",
11189e39c5baSBill Taylor DAPL_GET_CQE_STATUS(cqe_ptr),
11199e39c5baSBill Taylor DAPL_GET_CQE_OPTYPE(cqe_ptr));
11209e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
11219e39c5baSBill Taylor DAT_DTO_FAILURE;
11229e39c5baSBill Taylor break;
11239e39c5baSBill Taylor }
11249e39c5baSBill Taylor }
11259e39c5baSBill Taylor
11269e39c5baSBill Taylor /* Most error DTO ops result in disconnecting the EP */
11279e39c5baSBill Taylor if ((event_ptr->event_data.dto_completion_event_data.status !=
11289e39c5baSBill Taylor DAT_DTO_SUCCESS) &&
11299e39c5baSBill Taylor (event_ptr->event_data.dto_completion_event_data.status !=
11309e39c5baSBill Taylor DAT_RMR_OPERATION_FAILED)) {
11319e39c5baSBill Taylor dto_error = 1;
11329e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,
11339e39c5baSBill Taylor " DTO completion ERROR: %d: op %#x\n",
11349e39c5baSBill Taylor DAPL_GET_CQE_STATUS(cqe_ptr),
11359e39c5baSBill Taylor DAPL_GET_CQE_OPTYPE(cqe_ptr));
11369e39c5baSBill Taylor }
11379e39c5baSBill Taylor
11389e39c5baSBill Taylor if (cookie->val.dto.type == DAPL_DTO_TYPE_SEND ||
11399e39c5baSBill Taylor cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE) {
11409e39c5baSBill Taylor /* Get size from DTO; CQE value may be off. */
11419e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.
11429e39c5baSBill Taylor transfered_length = cookie->val.dto.size;
11439e39c5baSBill Taylor } else {
11449e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.
11459e39c5baSBill Taylor transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
11469e39c5baSBill Taylor }
11479e39c5baSBill Taylor
11489e39c5baSBill Taylor dapls_cookie_dealloc(buffer, cookie);
11499e39c5baSBill Taylor break;
11509e39c5baSBill Taylor }
11519e39c5baSBill Taylor
11529e39c5baSBill Taylor case DAPL_COOKIE_TYPE_RMR:
11539e39c5baSBill Taylor {
11549e39c5baSBill Taylor dapl_os_atomic_dec(&ep_ptr->req_count);
11559e39c5baSBill Taylor
11569e39c5baSBill Taylor event_ptr->event_number = DAT_RMR_BIND_COMPLETION_EVENT;
11579e39c5baSBill Taylor
11589e39c5baSBill Taylor event_ptr->event_data.rmr_completion_event_data.rmr_handle =
11599e39c5baSBill Taylor cookie->val.rmr.rmr;
11609e39c5baSBill Taylor event_ptr->event_data.rmr_completion_event_data.user_cookie =
11619e39c5baSBill Taylor cookie->val.rmr.cookie;
11629e39c5baSBill Taylor if (ib_status == IB_COMP_ST_SUCCESS) {
11639e39c5baSBill Taylor ibtype = DAPL_GET_CQE_OPTYPE(cqe_ptr);
11649e39c5baSBill Taylor
11659e39c5baSBill Taylor event_ptr->event_data.rmr_completion_event_data.status =
11669e39c5baSBill Taylor DAT_RMR_BIND_SUCCESS;
11679e39c5baSBill Taylor dapl_os_assert(ibtype == OP_BIND_MW);
11689e39c5baSBill Taylor } else {
11699e39c5baSBill Taylor event_ptr->event_data.rmr_completion_event_data.status =
11709e39c5baSBill Taylor DAT_RMR_BIND_FAILURE;
11719e39c5baSBill Taylor dto_error = 1;
11729e39c5baSBill Taylor }
11739e39c5baSBill Taylor
11749e39c5baSBill Taylor dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
11759e39c5baSBill Taylor break;
11769e39c5baSBill Taylor }
11779e39c5baSBill Taylor default:
11789e39c5baSBill Taylor {
11799e39c5baSBill Taylor dapl_os_assert(!"Invalid Operation type");
11809e39c5baSBill Taylor break;
11819e39c5baSBill Taylor }
11829e39c5baSBill Taylor }
11839e39c5baSBill Taylor
11849e39c5baSBill Taylor /*
11859e39c5baSBill Taylor * A DTO failed this will cause the connection to be broken
11869e39c5baSBill Taylor */
11879e39c5baSBill Taylor if ((dto_error) && (ep_ptr->param.ep_state == DAT_EP_STATE_CONNECTED)) {
11889e39c5baSBill Taylor ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
11899e39c5baSBill Taylor /*
11909e39c5baSBill Taylor * Disconnect at the IB level.
11919e39c5baSBill Taylor */
11929e39c5baSBill Taylor dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, IB_CME_CONNECTED);
11939e39c5baSBill Taylor }
11949e39c5baSBill Taylor /* convert premature rec to error flush on disconnect */
11959e39c5baSBill Taylor if (process_premature_events && (ep_ptr->param.ep_state ==
11969e39c5baSBill Taylor DAT_EP_STATE_DISCONNECTED) && (ib_status == IB_COMP_ST_SUCCESS)) {
11979e39c5baSBill Taylor dapl_os_assert(ibtype == OP_RECEIVE &&
11989e39c5baSBill Taylor cookie->val.dto.type == DAPL_DTO_TYPE_RECV);
11999e39c5baSBill Taylor event_ptr->event_data.dto_completion_event_data.status =
12009e39c5baSBill Taylor DAT_DTO_ERR_FLUSHED;
12019e39c5baSBill Taylor }
12029e39c5baSBill Taylor return (DAT_TRUE);
12039e39c5baSBill Taylor }
12049e39c5baSBill Taylor
12059e39c5baSBill Taylor /*
12069e39c5baSBill Taylor * dapls_evd_copy_cq
12079e39c5baSBill Taylor *
12089e39c5baSBill Taylor * Copy all entries on a CQ associated with the EVD onto that EVD
12099e39c5baSBill Taylor * Up to caller to handle races, if any. Note that no EVD waiters will
12109e39c5baSBill Taylor * be awoken by this copy.
12119e39c5baSBill Taylor *
12129e39c5baSBill Taylor * Input:
12139e39c5baSBill Taylor * evd_ptr
12149e39c5baSBill Taylor *
12159e39c5baSBill Taylor * Output:
1216*93fec3daSToomas Soome * nevents
12179e39c5baSBill Taylor *
12189e39c5baSBill Taylor * Returns:
1219*93fec3daSToomas Soome * none
12209e39c5baSBill Taylor *
12219e39c5baSBill Taylor */
12229e39c5baSBill Taylor void
dapls_evd_copy_cq(DAPL_EVD * evd_ptr,int * nevents)12239e39c5baSBill Taylor dapls_evd_copy_cq(
12249e39c5baSBill Taylor DAPL_EVD *evd_ptr,
12259e39c5baSBill Taylor int *nevents)
12269e39c5baSBill Taylor {
12279e39c5baSBill Taylor ib_work_completion_t cqe[MAX_CQES_PER_POLL];
12289e39c5baSBill Taylor DAT_RETURN dat_status;
12299e39c5baSBill Taylor ib_cq_handle_t cq_handle;
12309e39c5baSBill Taylor DAT_EVENT *event;
12319e39c5baSBill Taylor uint_t num_cqes_polled = 0;
12329e39c5baSBill Taylor int cqe_events;
12339e39c5baSBill Taylor int i;
12349e39c5baSBill Taylor
12359e39c5baSBill Taylor cq_handle = evd_ptr->ib_cq_handle;
12369e39c5baSBill Taylor
12379e39c5baSBill Taylor *nevents = 0;
12389e39c5baSBill Taylor
12399e39c5baSBill Taylor if (cq_handle == IB_INVALID_HANDLE) {
12409e39c5baSBill Taylor /* Nothing to do if no CQ. */
12419e39c5baSBill Taylor return;
12429e39c5baSBill Taylor }
12439e39c5baSBill Taylor dat_status = DAPL_POLL(evd_ptr)(cq_handle,
12449e39c5baSBill Taylor cqe, MAX_CQES_PER_POLL, &num_cqes_polled);
12459e39c5baSBill Taylor
12469e39c5baSBill Taylor if (dat_status == DAT_SUCCESS) {
12479e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD, "dapls_evd_copy_cq: %u\n",
12489e39c5baSBill Taylor num_cqes_polled);
12499e39c5baSBill Taylor cqe_events = 0;
12509e39c5baSBill Taylor for (i = 0; i < num_cqes_polled; i++) {
12519e39c5baSBill Taylor #ifdef DAPL_DBG /* For debugging. */
12529e39c5baSBill Taylor dapli_evd_eh_print_cqe(cqe[i]);
12539e39c5baSBill Taylor #endif
12549e39c5baSBill Taylor
12559e39c5baSBill Taylor /*
12569e39c5baSBill Taylor * Can use DAT_DTO_COMPLETION_EVENT because
12579e39c5baSBill Taylor * dapli_evd_cqe_to_event will overwrite.
12589e39c5baSBill Taylor */
12599e39c5baSBill Taylor
12609e39c5baSBill Taylor event = dapli_evd_get_and_init_event(
12619e39c5baSBill Taylor evd_ptr, DAT_DTO_COMPLETION_EVENT);
12629e39c5baSBill Taylor if (event == NULL) {
12639e39c5baSBill Taylor /*
12649e39c5baSBill Taylor * We've already attempted the overflow post; return.
12659e39c5baSBill Taylor */
12669e39c5baSBill Taylor return;
12679e39c5baSBill Taylor }
12689e39c5baSBill Taylor if (dapli_evd_cqe_to_event(evd_ptr, &cqe[i], DAT_FALSE,
12699e39c5baSBill Taylor event)) {
12709e39c5baSBill Taylor dapli_evd_post_event_nosignal(evd_ptr, event);
12719e39c5baSBill Taylor cqe_events++;
12729e39c5baSBill Taylor } else {
12739e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
12749e39c5baSBill Taylor "dapls_evd_copy_cq: premature event\n");
12759e39c5baSBill Taylor /*
12769e39c5baSBill Taylor * We've deferred processing the CQE, so add
12779e39c5baSBill Taylor * the event_ptr back to free queue
12789e39c5baSBill Taylor */
12799e39c5baSBill Taylor dat_status = dapls_rbuf_add(&evd_ptr->
12809e39c5baSBill Taylor free_event_queue, (void *)event);
12819e39c5baSBill Taylor dapl_os_assert(dat_status == DAT_SUCCESS);
12829e39c5baSBill Taylor if (evd_ptr->evd_producer_locking_needed) {
12839e39c5baSBill Taylor dapl_os_unlock(&evd_ptr->header.lock);
12849e39c5baSBill Taylor }
12859e39c5baSBill Taylor }
12869e39c5baSBill Taylor }
12879e39c5baSBill Taylor *nevents = cqe_events;
12889e39c5baSBill Taylor } else if (DAT_GET_TYPE(dat_status) != DAT_QUEUE_EMPTY) {
12899e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
12909e39c5baSBill Taylor "dapls_evd_copy_cq: dapls_ib_completion_poll "
12919e39c5baSBill Taylor "returned 0x%x\n", dat_status);
12929e39c5baSBill Taylor dapl_os_assert(!"Bad return from dapls_ib_completion_poll");
12939e39c5baSBill Taylor }
12949e39c5baSBill Taylor }
12959e39c5baSBill Taylor
12969e39c5baSBill Taylor /*
12979e39c5baSBill Taylor * dapls_evd_copy_events
12989e39c5baSBill Taylor *
12999e39c5baSBill Taylor * Copy all events associated with the EVD onto that EVD
13009e39c5baSBill Taylor *
13019e39c5baSBill Taylor * Input:
13029e39c5baSBill Taylor * evd_ptr
13039e39c5baSBill Taylor * timeout
13049e39c5baSBill Taylor *
13059e39c5baSBill Taylor * Output:
1306*93fec3daSToomas Soome * return status
13079e39c5baSBill Taylor *
13089e39c5baSBill Taylor * Returns:
1309*93fec3daSToomas Soome * none
13109e39c5baSBill Taylor *
13119e39c5baSBill Taylor */
13129e39c5baSBill Taylor DAT_RETURN
dapls_evd_copy_events(DAPL_EVD * evd_ptr,DAT_TIMEOUT timeout)1313*93fec3daSToomas Soome dapls_evd_copy_events(DAPL_EVD *evd_ptr, DAT_TIMEOUT timeout)
13149e39c5baSBill Taylor {
13159e39c5baSBill Taylor dapl_ib_event_t evp_arr[NUM_EVENTS_PER_POLL];
13169e39c5baSBill Taylor dapl_ib_event_t *evpp_start;
13179e39c5baSBill Taylor dapl_ib_event_t *evpp;
13189e39c5baSBill Taylor DAPL_IA *ia_ptr;
13199e39c5baSBill Taylor DAT_RETURN dat_status;
13209e39c5baSBill Taylor int waited;
13219e39c5baSBill Taylor uint64_t curr_time;
13229e39c5baSBill Taylor uint64_t final_time;
13239e39c5baSBill Taylor uint64_t time_left;
13249e39c5baSBill Taylor int events_needed = 0;
13259e39c5baSBill Taylor int nevents = 0;
13269e39c5baSBill Taylor int num_cqe = 0;
13279e39c5baSBill Taylor int num_ke = 0; /* kernel events - CM or ASYNC events */
13289e39c5baSBill Taylor int i;
13299e39c5baSBill Taylor
13309e39c5baSBill Taylor /* rbuf count is zero on entry */
13319e39c5baSBill Taylor
13329e39c5baSBill Taylor if (evd_ptr->evd_flags & (DAT_EVD_CONNECTION_FLAG |
13339e39c5baSBill Taylor DAT_EVD_CR_FLAG | DAT_EVD_ASYNC_FLAG)) {
13349e39c5baSBill Taylor if (evd_ptr->threshold <= NUM_EVENTS_PER_POLL) {
13359e39c5baSBill Taylor evpp = evp_arr;
13369e39c5baSBill Taylor } else {
13379e39c5baSBill Taylor /* need to allocate on the heap */
13389e39c5baSBill Taylor evpp = (dapl_ib_event_t *)dapl_os_alloc(
13399e39c5baSBill Taylor evd_ptr->threshold * sizeof (dapl_ib_event_t));
13409e39c5baSBill Taylor if (evpp == NULL) {
13419e39c5baSBill Taylor return (DAT_INSUFFICIENT_RESOURCES);
13429e39c5baSBill Taylor }
13439e39c5baSBill Taylor }
13449e39c5baSBill Taylor evpp_start = evpp;
13459e39c5baSBill Taylor /* for evd_dequeue, check for ke before returning Q_EMPTY */
13469e39c5baSBill Taylor if (evd_ptr->threshold == 0 && timeout == 0)
13479e39c5baSBill Taylor evd_ptr->threshold = 1;
13489e39c5baSBill Taylor } else {
13499e39c5baSBill Taylor evpp = NULL;
13509e39c5baSBill Taylor evpp_start = NULL;
13519e39c5baSBill Taylor }
13529e39c5baSBill Taylor ia_ptr = evd_ptr->header.owner_ia;
13539e39c5baSBill Taylor waited = 0;
13549e39c5baSBill Taylor dat_status = DAT_SUCCESS;
13559e39c5baSBill Taylor
13569e39c5baSBill Taylor /* calculate various time wait elements */
13579e39c5baSBill Taylor if (timeout == 0) {
13589e39c5baSBill Taylor final_time = 0;
13599e39c5baSBill Taylor time_left = 0;
13609e39c5baSBill Taylor } else if (timeout == DAT_TIMEOUT_INFINITE) {
13619e39c5baSBill Taylor /*
13629e39c5baSBill Taylor * The real value of DAT_TIMEOUT_INFINITE is fairly small
13639e39c5baSBill Taylor * ~71 mins, to prevent premature timeouts map it to
13649e39c5baSBill Taylor * 1 year. NOTE: 64-bit integers are needed here
13659e39c5baSBill Taylor * because 32 bits is not enough. Other types,
13669e39c5baSBill Taylor * such as clock_t are not 64-bit, so are not
13679e39c5baSBill Taylor * sufficient for this. Similarly, hrtime_t is
13689e39c5baSBill Taylor * defined as a "nanosecond counter", which does not
13699e39c5baSBill Taylor * match our need for time in microseconds, so we
13709e39c5baSBill Taylor * just use the more general uint64_t here.
13719e39c5baSBill Taylor */
13729e39c5baSBill Taylor #define DAPL_ONE_YEAR_IN_USEC ((365 * 24 * 3600) * 1000000LL)
13739e39c5baSBill Taylor curr_time = gethrtime();
13749e39c5baSBill Taylor time_left = DAPL_ONE_YEAR_IN_USEC;
13759e39c5baSBill Taylor final_time = curr_time + DAPL_ONE_YEAR_IN_USEC * 1000;
13769e39c5baSBill Taylor } else {
13779e39c5baSBill Taylor /*
13789e39c5baSBill Taylor * maximum time by which the routine needs to return
13799e39c5baSBill Taylor * DAT_TIMEOUT_INFINITE is defined as ~0 but its of type int
13809e39c5baSBill Taylor * so mask the MSB to avoid overflow
13819e39c5baSBill Taylor */
13829e39c5baSBill Taylor curr_time = gethrtime();
13839e39c5baSBill Taylor final_time = curr_time + (uint64_t)(timeout&0x7fffffff)*1000;
13849e39c5baSBill Taylor time_left = (final_time - curr_time)/1000;
13859e39c5baSBill Taylor }
13869e39c5baSBill Taylor
13879e39c5baSBill Taylor do {
13889e39c5baSBill Taylor /*
13899e39c5baSBill Taylor * If this evd has a CQ event stream check the CQs first
13909e39c5baSBill Taylor */
13919e39c5baSBill Taylor if (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG |
13929e39c5baSBill Taylor DAT_EVD_RMR_BIND_FLAG)) {
13939e39c5baSBill Taylor /*
13949e39c5baSBill Taylor * Poll CQ for events, update the total number of CQEs
13959e39c5baSBill Taylor * so far
13969e39c5baSBill Taylor */
13979e39c5baSBill Taylor nevents = 0;
13989e39c5baSBill Taylor dapls_evd_copy_cq(evd_ptr, &nevents);
13999e39c5baSBill Taylor num_cqe += nevents;
14009e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
14019e39c5baSBill Taylor "dapls_evd_copy_event: copy_cq num_cqe(%d)\n",
14029e39c5baSBill Taylor num_cqe);
14039e39c5baSBill Taylor }
14049e39c5baSBill Taylor
14059e39c5baSBill Taylor /*
14069e39c5baSBill Taylor * We use the dapls_rbuf_count since it includes
14079e39c5baSBill Taylor * - CQ events pulled by dapls_evd_copy_cq
14089e39c5baSBill Taylor * - events added by dat_evd_post_se()
14099e39c5baSBill Taylor */
14109e39c5baSBill Taylor events_needed = evd_ptr->threshold - num_ke -
14119e39c5baSBill Taylor dapls_rbuf_count(&evd_ptr->pending_event_queue);
14129e39c5baSBill Taylor
14139e39c5baSBill Taylor /*
14149e39c5baSBill Taylor * check for pending events
14159e39c5baSBill Taylor * note: threshold=0 implies dapl_evd_dequeue
14169e39c5baSBill Taylor */
14179e39c5baSBill Taylor if (events_needed < 0) {
14189e39c5baSBill Taylor /* There are more than sufficient events */
14199e39c5baSBill Taylor break;
14209e39c5baSBill Taylor } else if (events_needed == 0) {
14219e39c5baSBill Taylor /* report queue empty on dat_evd_dequeue */
14229e39c5baSBill Taylor /* non CQ events are expected to be polled */
14239e39c5baSBill Taylor /* by dat_evd_wait */
14249e39c5baSBill Taylor if (evd_ptr->threshold == 0)
14259e39c5baSBill Taylor dat_status = DAT_ERROR(DAT_QUEUE_EMPTY, 0);
14269e39c5baSBill Taylor /*
14279e39c5baSBill Taylor * when threshold > 0, we have sufficient events
14289e39c5baSBill Taylor */
14299e39c5baSBill Taylor break;
14309e39c5baSBill Taylor } else {
14319e39c5baSBill Taylor /*
14329e39c5baSBill Taylor * when we reach here, this implies dat_evd_wait
14339e39c5baSBill Taylor * return on any dto completion as
14349e39c5baSBill Taylor * threshold > 1 will be taken as hint only
14359e39c5baSBill Taylor */
14369e39c5baSBill Taylor if (num_cqe)
14379e39c5baSBill Taylor break;
14389e39c5baSBill Taylor }
14399e39c5baSBill Taylor
14409e39c5baSBill Taylor /* check we've already waited */
14419e39c5baSBill Taylor if (waited > 0) {
14429e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
14439e39c5baSBill Taylor "dapls_evd_copy_event: waited[%d]\n", waited);
14449e39c5baSBill Taylor if (dat_status != DAT_SUCCESS)
14459e39c5baSBill Taylor break;
14469e39c5baSBill Taylor curr_time = gethrtime();
14479e39c5baSBill Taylor /* exit on time expired */
14489e39c5baSBill Taylor if (curr_time >= final_time)
14499e39c5baSBill Taylor break;
14509e39c5baSBill Taylor time_left = (final_time - curr_time)/1000;
14519e39c5baSBill Taylor }
14529e39c5baSBill Taylor
14539e39c5baSBill Taylor /* check for DTO type evd's */
14549e39c5baSBill Taylor if (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG |
14559e39c5baSBill Taylor DAT_EVD_RMR_BIND_FLAG)) {
14569e39c5baSBill Taylor if (events_needed == 1) {
14579e39c5baSBill Taylor /*
14589e39c5baSBill Taylor * Need only one event so enable cq
14599e39c5baSBill Taylor * notification
14609e39c5baSBill Taylor */
14619e39c5baSBill Taylor /*
14629e39c5baSBill Taylor * XXX: Things need to be modified here to
14639e39c5baSBill Taylor * implement the NOTIFICATION suppression
14649e39c5baSBill Taylor * correctly - relies on THRESHOLD flag
14659e39c5baSBill Taylor * and UNSIGNALLED flag to be stored
14669e39c5baSBill Taylor * in the evd.
14679e39c5baSBill Taylor */
14689e39c5baSBill Taylor dat_status = dapls_set_cq_notify(ia_ptr,
14699e39c5baSBill Taylor evd_ptr);
14709e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
14719e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
14729e39c5baSBill Taylor "dapls_evd_copy_event:"
14739e39c5baSBill Taylor " set_cq_notify(%d)\n", dat_status);
14749e39c5baSBill Taylor return (dat_status);
14759e39c5baSBill Taylor }
14769e39c5baSBill Taylor } else if (events_needed > 1) {
14779e39c5baSBill Taylor /*
14789e39c5baSBill Taylor * We need multiple events so lets enable CQ for
14799e39c5baSBill Taylor * notification on N events.
14809e39c5baSBill Taylor * dat_status = dapls_set_cqN_notify(ia_ptr,
14819e39c5baSBill Taylor * evd_ptr, (uint32_t)events_needed);
14829e39c5baSBill Taylor */
14839e39c5baSBill Taylor dat_status = dapls_set_cq_notify(ia_ptr,
14849e39c5baSBill Taylor evd_ptr);
14859e39c5baSBill Taylor if (dat_status != DAT_SUCCESS) {
14869e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
14879e39c5baSBill Taylor "dapls_evd_copy_event:"
14889e39c5baSBill Taylor " set_cqN_notify:%d\n", dat_status);
14899e39c5baSBill Taylor return (dat_status);
14909e39c5baSBill Taylor }
14919e39c5baSBill Taylor }
14929e39c5baSBill Taylor
14939e39c5baSBill Taylor /*
14949e39c5baSBill Taylor * Per Tavor PRM if completions occur after polling
14959e39c5baSBill Taylor * the CQ and before arming it, upon arming the CQ
14969e39c5baSBill Taylor * handler will be immediately fired. Hence it
14979e39c5baSBill Taylor * recommends that a re-poll of the CQ can be skipped
14989e39c5baSBill Taylor * as an optimization.
14999e39c5baSBill Taylor */
15009e39c5baSBill Taylor }
15019e39c5baSBill Taylor
15029e39c5baSBill Taylor nevents = 0;
15039e39c5baSBill Taylor
15049e39c5baSBill Taylor /*
15059e39c5baSBill Taylor * non-NULL evpp_start denotes either
15069e39c5baSBill Taylor * DAT_EVD_CONNECTION_FLAG, DAT_EVD_CR_FLAG, DAT_EVD_ASYNC_FLAG
15079e39c5baSBill Taylor * is set and thus needs to check events from kernel
15089e39c5baSBill Taylor */
15099e39c5baSBill Taylor if (evpp_start) {
15109e39c5baSBill Taylor /*
15119e39c5baSBill Taylor * Even if dat_status is not DAT_SUCCESS, num_events
15129e39c5baSBill Taylor * could be non-zero.
15139e39c5baSBill Taylor */
15149e39c5baSBill Taylor dat_status = dapls_ib_event_poll(evd_ptr, time_left,
15159e39c5baSBill Taylor (evd_ptr->threshold - (num_cqe + num_ke)), evpp,
15169e39c5baSBill Taylor &nevents);
15179e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
15189e39c5baSBill Taylor "dapls_evd_copy_event: poll returned 0x%x(%d)\n",
15199e39c5baSBill Taylor dat_status, nevents);
15209e39c5baSBill Taylor
15219e39c5baSBill Taylor num_ke += nevents;
15229e39c5baSBill Taylor evpp += nevents;
15239e39c5baSBill Taylor } else {
15249e39c5baSBill Taylor /* perform a timewait */
15259e39c5baSBill Taylor dat_status = dapls_ib_event_poll(evd_ptr, time_left,
15269e39c5baSBill Taylor 0, NULL, &nevents);
15279e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
15289e39c5baSBill Taylor "dapls_evd_copy_event: poll(cq_notification) "
15299e39c5baSBill Taylor "returned 0x%x\n", dat_status);
15309e39c5baSBill Taylor if (DAT_GET_TYPE(dat_status) == DAT_INTERRUPTED_CALL)
15319e39c5baSBill Taylor return (dat_status);
15329e39c5baSBill Taylor }
15339e39c5baSBill Taylor
15349e39c5baSBill Taylor waited++;
15359e39c5baSBill Taylor } while (dapls_rbuf_count(&evd_ptr->pending_event_queue) + num_ke <
15369e39c5baSBill Taylor evd_ptr->threshold);
15379e39c5baSBill Taylor
15389e39c5baSBill Taylor /* process the cm events now */
15399e39c5baSBill Taylor for (i = 0; i < num_ke; i++) {
15409e39c5baSBill Taylor switch (evpp_start[i].ibe_ev_family) {
15419e39c5baSBill Taylor case DAPL_CR_EVENTS: /* PASSIVE side events */
15429e39c5baSBill Taylor case DAPL_PASSIVE_CONNECTION_EVENTS:
15439e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
15449e39c5baSBill Taylor "dapls_evd_copy_event: Passive side Event %d\n",
15459e39c5baSBill Taylor evpp_start[i].ibe_ce.ibce_event);
15469e39c5baSBill Taylor dapls_cr_callback((ib_cm_handle_t)
15479e39c5baSBill Taylor evpp_start[i].ibe_ce.ibce_psep_cookie,
15489e39c5baSBill Taylor evpp_start[i].ibe_ce.ibce_event,
15499e39c5baSBill Taylor evpp_start[i].ibe_ce.ibce_priv_data_ptr, (void *)
15509e39c5baSBill Taylor (uintptr_t)evpp_start[i].ibe_ce.ibce_cookie);
15519e39c5baSBill Taylor break;
15529e39c5baSBill Taylor case DAPL_ACTIVE_CONNECTION_EVENTS: /* ACTIVE side events */
15539e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
15549e39c5baSBill Taylor "dapls_evd_copy_event: Active Conn Event %d\n",
15559e39c5baSBill Taylor evpp_start[i].ibe_ce.ibce_event);
15569e39c5baSBill Taylor dapl_evd_connection_callback((ib_cm_handle_t)
15579e39c5baSBill Taylor IB_INVALID_HANDLE,
15589e39c5baSBill Taylor evpp_start[i].ibe_ce.ibce_event,
15599e39c5baSBill Taylor evpp_start[i].ibe_ce.ibce_priv_data_ptr, (void *)
15609e39c5baSBill Taylor (uintptr_t)evpp_start[i].ibe_ce.ibce_cookie);
15619e39c5baSBill Taylor break;
15629e39c5baSBill Taylor case DAPL_ASYNC_EVENTS:
15639e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_EVD,
15649e39c5baSBill Taylor "dapls_evd_copy_event: Async Event %d\n",
15659e39c5baSBill Taylor evpp_start[i].ibe_async.ibae_type);
15669e39c5baSBill Taylor dapls_ib_async_callback(evd_ptr,
15679e39c5baSBill Taylor ia_ptr->hca_ptr->ib_hca_handle,
15689e39c5baSBill Taylor &(evpp_start[i].ibe_async), ia_ptr);
15699e39c5baSBill Taylor break;
15709e39c5baSBill Taylor default:
15719e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
15729e39c5baSBill Taylor "dapls_evd_copy_event: dapls_ib_event_poll %d "
15739e39c5baSBill Taylor "returned 0x%x\n", i, evpp_start[i].ibe_ev_family);
15749e39c5baSBill Taylor dapl_os_assert(!"Bad return from dapls_ib_event_poll");
15759e39c5baSBill Taylor break;
15769e39c5baSBill Taylor }
15779e39c5baSBill Taylor }
15789e39c5baSBill Taylor
15799e39c5baSBill Taylor return (dat_status);
15809e39c5baSBill Taylor }
15819e39c5baSBill Taylor
15829e39c5baSBill Taylor /*
15839e39c5baSBill Taylor * dapls_evd_cq_poll_to_event
15849e39c5baSBill Taylor *
15859e39c5baSBill Taylor * Attempt to dequeue a single CQE from a CQ and turn it into
15869e39c5baSBill Taylor * an event.
15879e39c5baSBill Taylor *
15889e39c5baSBill Taylor * Input:
15899e39c5baSBill Taylor * evd_ptr
15909e39c5baSBill Taylor *
15919e39c5baSBill Taylor * Output:
1592*93fec3daSToomas Soome * event
15939e39c5baSBill Taylor *
15949e39c5baSBill Taylor * Returns:
1595*93fec3daSToomas Soome * Status of operation
15969e39c5baSBill Taylor *
15979e39c5baSBill Taylor */
15989e39c5baSBill Taylor DAT_RETURN
dapls_evd_cq_poll_to_event(IN DAPL_EVD * evd_ptr,OUT DAT_EVENT * event)1599*93fec3daSToomas Soome dapls_evd_cq_poll_to_event(IN DAPL_EVD *evd_ptr, OUT DAT_EVENT *event)
16009e39c5baSBill Taylor {
16019e39c5baSBill Taylor DAT_RETURN dat_status;
16029e39c5baSBill Taylor ib_work_completion_t cur_cqe;
16039e39c5baSBill Taylor
16049e39c5baSBill Taylor /* skip one layer of do-nothing function */
16059e39c5baSBill Taylor dat_status = DAPL_POLL1(evd_ptr)(evd_ptr->ib_cq_handle, &cur_cqe);
16069e39c5baSBill Taylor
16079e39c5baSBill Taylor if (dat_status == DAT_SUCCESS) {
16089e39c5baSBill Taylor #ifdef DAPL_DBG /* For debugging. */
16099e39c5baSBill Taylor dapli_evd_eh_print_cqe(cur_cqe);
16109e39c5baSBill Taylor #endif
16119e39c5baSBill Taylor (void) dapli_evd_cqe_to_event(evd_ptr, &cur_cqe, DAT_FALSE,
16129e39c5baSBill Taylor event);
16139e39c5baSBill Taylor }
16149e39c5baSBill Taylor
16159e39c5baSBill Taylor return (dat_status);
16169e39c5baSBill Taylor }
16179e39c5baSBill Taylor
16189e39c5baSBill Taylor /*
16199e39c5baSBill Taylor * Local variables:
16209e39c5baSBill Taylor * c-indent-level: 4
16219e39c5baSBill Taylor * c-basic-offset: 4
16229e39c5baSBill Taylor * tab-width: 8
16239e39c5baSBill Taylor * End:
16249e39c5baSBill Taylor */
1625