1*d6b92ffaSHans Petter Selasky /* 2*d6b92ffaSHans Petter Selasky * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved. 3*d6b92ffaSHans Petter Selasky * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 4*d6b92ffaSHans Petter Selasky * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved. 5*d6b92ffaSHans Petter Selasky * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 6*d6b92ffaSHans Petter Selasky * 7*d6b92ffaSHans Petter Selasky * This software is available to you under a choice of one of two 8*d6b92ffaSHans Petter Selasky * licenses. You may choose to be licensed under the terms of the GNU 9*d6b92ffaSHans Petter Selasky * General Public License (GPL) Version 2, available from the file 10*d6b92ffaSHans Petter Selasky * COPYING in the main directory of this source tree, or the 11*d6b92ffaSHans Petter Selasky * OpenIB.org BSD license below: 12*d6b92ffaSHans Petter Selasky * 13*d6b92ffaSHans Petter Selasky * Redistribution and use in source and binary forms, with or 14*d6b92ffaSHans Petter Selasky * without modification, are permitted provided that the following 15*d6b92ffaSHans Petter Selasky * conditions are met: 16*d6b92ffaSHans Petter Selasky * 17*d6b92ffaSHans Petter Selasky * - Redistributions of source code must retain the above 18*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following 19*d6b92ffaSHans Petter Selasky * disclaimer. 20*d6b92ffaSHans Petter Selasky * 21*d6b92ffaSHans Petter Selasky * - Redistributions in binary form must reproduce the above 22*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following 23*d6b92ffaSHans Petter Selasky * disclaimer in the documentation and/or other materials 24*d6b92ffaSHans Petter Selasky * provided with the distribution. 25*d6b92ffaSHans Petter Selasky * 26*d6b92ffaSHans Petter Selasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27*d6b92ffaSHans Petter Selasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28*d6b92ffaSHans Petter Selasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29*d6b92ffaSHans Petter Selasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30*d6b92ffaSHans Petter Selasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31*d6b92ffaSHans Petter Selasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32*d6b92ffaSHans Petter Selasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33*d6b92ffaSHans Petter Selasky * SOFTWARE. 34*d6b92ffaSHans Petter Selasky * 35*d6b92ffaSHans Petter Selasky */ 36*d6b92ffaSHans Petter Selasky 37*d6b92ffaSHans Petter Selasky /* 38*d6b92ffaSHans Petter Selasky * Abstract: 39*d6b92ffaSHans Petter Selasky * Implementation of osm_vl15_t. 40*d6b92ffaSHans Petter Selasky * This object represents the VL15 Interface object. 41*d6b92ffaSHans Petter Selasky * This object is part of the opensm family of objects. 42*d6b92ffaSHans Petter Selasky */ 43*d6b92ffaSHans Petter Selasky 44*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H 45*d6b92ffaSHans Petter Selasky # include <config.h> 46*d6b92ffaSHans Petter Selasky #endif /* HAVE_CONFIG_H */ 47*d6b92ffaSHans Petter Selasky 48*d6b92ffaSHans Petter Selasky #include <string.h> 49*d6b92ffaSHans Petter Selasky #include <iba/ib_types.h> 50*d6b92ffaSHans Petter Selasky #include <complib/cl_thread.h> 51*d6b92ffaSHans Petter Selasky #include <opensm/osm_file_ids.h> 52*d6b92ffaSHans Petter Selasky #define FILE_ID OSM_FILE_VL15INTF_C 53*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_api.h> 54*d6b92ffaSHans Petter Selasky #include <opensm/osm_vl15intf.h> 55*d6b92ffaSHans Petter Selasky #include <opensm/osm_madw.h> 56*d6b92ffaSHans Petter Selasky #include <opensm/osm_log.h> 57*d6b92ffaSHans Petter Selasky #include <opensm/osm_helper.h> 58*d6b92ffaSHans Petter Selasky 59*d6b92ffaSHans Petter Selasky static void vl15_send_mad(osm_vl15_t * p_vl, osm_madw_t * p_madw) 60*d6b92ffaSHans Petter Selasky { 61*d6b92ffaSHans Petter Selasky ib_api_status_t status; 62*d6b92ffaSHans Petter Selasky boolean_t resp_expected = p_madw->resp_expected; 63*d6b92ffaSHans Petter Selasky ib_smp_t * p_smp; 64*d6b92ffaSHans Petter Selasky ib_net16_t attr_id; 65*d6b92ffaSHans Petter Selasky uint8_t method; 66*d6b92ffaSHans Petter Selasky 67*d6b92ffaSHans Petter Selasky p_smp = osm_madw_get_smp_ptr(p_madw); 68*d6b92ffaSHans Petter Selasky method = p_smp->method; 69*d6b92ffaSHans Petter Selasky attr_id = p_smp->attr_id; 70*d6b92ffaSHans Petter Selasky 71*d6b92ffaSHans Petter Selasky /* 72*d6b92ffaSHans Petter Selasky Non-response-expected mads are not throttled on the wire 73*d6b92ffaSHans Petter Selasky since we can have no confirmation that they arrived 74*d6b92ffaSHans Petter Selasky at their destination. 75*d6b92ffaSHans Petter Selasky */ 76*d6b92ffaSHans Petter Selasky if (resp_expected) 77*d6b92ffaSHans Petter Selasky /* 78*d6b92ffaSHans Petter Selasky Note that other threads may not see the response MAD 79*d6b92ffaSHans Petter Selasky arrive before send() even returns. 80*d6b92ffaSHans Petter Selasky In that case, the wire count would temporarily go negative. 81*d6b92ffaSHans Petter Selasky To avoid this confusion, preincrement the counts on the 82*d6b92ffaSHans Petter Selasky assumption that send() will succeed. 83*d6b92ffaSHans Petter Selasky */ 84*d6b92ffaSHans Petter Selasky cl_atomic_inc(&p_vl->p_stats->qp0_mads_outstanding_on_wire); 85*d6b92ffaSHans Petter Selasky else 86*d6b92ffaSHans Petter Selasky cl_atomic_inc(&p_vl->p_stats->qp0_unicasts_sent); 87*d6b92ffaSHans Petter Selasky 88*d6b92ffaSHans Petter Selasky cl_atomic_inc(&p_vl->p_stats->qp0_mads_sent); 89*d6b92ffaSHans Petter Selasky 90*d6b92ffaSHans Petter Selasky status = osm_vendor_send(osm_madw_get_bind_handle(p_madw), 91*d6b92ffaSHans Petter Selasky p_madw, p_madw->resp_expected); 92*d6b92ffaSHans Petter Selasky 93*d6b92ffaSHans Petter Selasky if (status == IB_SUCCESS) { 94*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, 95*d6b92ffaSHans Petter Selasky "%u QP0 MADs on wire, %u outstanding, " 96*d6b92ffaSHans Petter Selasky "%u unicasts sent, %u total sent\n", 97*d6b92ffaSHans Petter Selasky p_vl->p_stats->qp0_mads_outstanding_on_wire, 98*d6b92ffaSHans Petter Selasky p_vl->p_stats->qp0_mads_outstanding, 99*d6b92ffaSHans Petter Selasky p_vl->p_stats->qp0_unicasts_sent, 100*d6b92ffaSHans Petter Selasky p_vl->p_stats->qp0_mads_sent); 101*d6b92ffaSHans Petter Selasky return; 102*d6b92ffaSHans Petter Selasky } 103*d6b92ffaSHans Petter Selasky 104*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_ERROR, "ERR 3E03: " 105*d6b92ffaSHans Petter Selasky "MAD send failed (%s)\n", ib_get_err_str(status)); 106*d6b92ffaSHans Petter Selasky 107*d6b92ffaSHans Petter Selasky /* 108*d6b92ffaSHans Petter Selasky The MAD was never successfully sent, so 109*d6b92ffaSHans Petter Selasky fix up the pre-incremented count values. 110*d6b92ffaSHans Petter Selasky */ 111*d6b92ffaSHans Petter Selasky 112*d6b92ffaSHans Petter Selasky /* Decrement qp0_mads_sent that were incremented in the code above. 113*d6b92ffaSHans Petter Selasky qp0_mads_outstanding will be decremented by send error callback 114*d6b92ffaSHans Petter Selasky (called by osm_vendor_send() */ 115*d6b92ffaSHans Petter Selasky cl_atomic_dec(&p_vl->p_stats->qp0_mads_sent); 116*d6b92ffaSHans Petter Selasky if (!resp_expected) { 117*d6b92ffaSHans Petter Selasky cl_atomic_dec(&p_vl->p_stats->qp0_unicasts_sent); 118*d6b92ffaSHans Petter Selasky return; 119*d6b92ffaSHans Petter Selasky } 120*d6b92ffaSHans Petter Selasky 121*d6b92ffaSHans Petter Selasky /* need to cause heavy-sweep if resp_expected MAD sending failed */ 122*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_ERROR, "ERR 3E04: " 123*d6b92ffaSHans Petter Selasky "%s method failed for attribute 0x%X (%s)\n", 124*d6b92ffaSHans Petter Selasky method == IB_MAD_METHOD_SET ? "SET" : "GET", 125*d6b92ffaSHans Petter Selasky cl_ntoh16(attr_id), ib_get_sm_attr_str(attr_id)); 126*d6b92ffaSHans Petter Selasky 127*d6b92ffaSHans Petter Selasky p_vl->p_subn->subnet_initialization_error = TRUE; 128*d6b92ffaSHans Petter Selasky 129*d6b92ffaSHans Petter Selasky } 130*d6b92ffaSHans Petter Selasky 131*d6b92ffaSHans Petter Selasky static void vl15_poller(IN void *p_ptr) 132*d6b92ffaSHans Petter Selasky { 133*d6b92ffaSHans Petter Selasky ib_api_status_t status; 134*d6b92ffaSHans Petter Selasky osm_madw_t *p_madw; 135*d6b92ffaSHans Petter Selasky osm_vl15_t *p_vl = p_ptr; 136*d6b92ffaSHans Petter Selasky cl_qlist_t *p_fifo; 137*d6b92ffaSHans Petter Selasky int32_t max_smps = p_vl->max_wire_smps; 138*d6b92ffaSHans Petter Selasky int32_t max_smps2 = p_vl->max_wire_smps2; 139*d6b92ffaSHans Petter Selasky 140*d6b92ffaSHans Petter Selasky OSM_LOG_ENTER(p_vl->p_log); 141*d6b92ffaSHans Petter Selasky 142*d6b92ffaSHans Petter Selasky if (p_vl->thread_state == OSM_THREAD_STATE_NONE) 143*d6b92ffaSHans Petter Selasky p_vl->thread_state = OSM_THREAD_STATE_RUN; 144*d6b92ffaSHans Petter Selasky 145*d6b92ffaSHans Petter Selasky while (p_vl->thread_state == OSM_THREAD_STATE_RUN) { 146*d6b92ffaSHans Petter Selasky /* 147*d6b92ffaSHans Petter Selasky Start servicing the FIFOs by pulling off MAD wrappers 148*d6b92ffaSHans Petter Selasky and passing them to the transport interface. 149*d6b92ffaSHans Petter Selasky There are lots of corner cases here so tread carefully. 150*d6b92ffaSHans Petter Selasky 151*d6b92ffaSHans Petter Selasky The unicast FIFO has priority, since somebody is waiting 152*d6b92ffaSHans Petter Selasky for a timely response. 153*d6b92ffaSHans Petter Selasky */ 154*d6b92ffaSHans Petter Selasky cl_spinlock_acquire(&p_vl->lock); 155*d6b92ffaSHans Petter Selasky 156*d6b92ffaSHans Petter Selasky if (cl_qlist_count(&p_vl->ufifo) != 0) 157*d6b92ffaSHans Petter Selasky p_fifo = &p_vl->ufifo; 158*d6b92ffaSHans Petter Selasky else 159*d6b92ffaSHans Petter Selasky p_fifo = &p_vl->rfifo; 160*d6b92ffaSHans Petter Selasky 161*d6b92ffaSHans Petter Selasky p_madw = (osm_madw_t *) cl_qlist_remove_head(p_fifo); 162*d6b92ffaSHans Petter Selasky 163*d6b92ffaSHans Petter Selasky cl_spinlock_release(&p_vl->lock); 164*d6b92ffaSHans Petter Selasky 165*d6b92ffaSHans Petter Selasky if (p_madw != (osm_madw_t *) cl_qlist_end(p_fifo)) { 166*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, 167*d6b92ffaSHans Petter Selasky "Servicing p_madw = %p\n", p_madw); 168*d6b92ffaSHans Petter Selasky if (OSM_LOG_IS_ACTIVE_V2(p_vl->p_log, OSM_LOG_FRAMES)) 169*d6b92ffaSHans Petter Selasky osm_dump_dr_smp_v2(p_vl->p_log, 170*d6b92ffaSHans Petter Selasky osm_madw_get_smp_ptr(p_madw), 171*d6b92ffaSHans Petter Selasky FILE_ID, OSM_LOG_FRAMES); 172*d6b92ffaSHans Petter Selasky 173*d6b92ffaSHans Petter Selasky vl15_send_mad(p_vl, p_madw); 174*d6b92ffaSHans Petter Selasky } else 175*d6b92ffaSHans Petter Selasky /* 176*d6b92ffaSHans Petter Selasky The VL15 FIFO is empty, so we have nothing left to do. 177*d6b92ffaSHans Petter Selasky */ 178*d6b92ffaSHans Petter Selasky status = cl_event_wait_on(&p_vl->signal, 179*d6b92ffaSHans Petter Selasky EVENT_NO_TIMEOUT, TRUE); 180*d6b92ffaSHans Petter Selasky 181*d6b92ffaSHans Petter Selasky while (p_vl->p_stats->qp0_mads_outstanding_on_wire >= max_smps && 182*d6b92ffaSHans Petter Selasky p_vl->thread_state == OSM_THREAD_STATE_RUN) { 183*d6b92ffaSHans Petter Selasky status = cl_event_wait_on(&p_vl->signal, 184*d6b92ffaSHans Petter Selasky p_vl->max_smps_timeout, 185*d6b92ffaSHans Petter Selasky TRUE); 186*d6b92ffaSHans Petter Selasky if (status == CL_TIMEOUT) { 187*d6b92ffaSHans Petter Selasky if (max_smps < max_smps2) 188*d6b92ffaSHans Petter Selasky max_smps++; 189*d6b92ffaSHans Petter Selasky break; 190*d6b92ffaSHans Petter Selasky } else if (status != CL_SUCCESS) { 191*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_ERROR, "ERR 3E02: " 192*d6b92ffaSHans Petter Selasky "Event wait failed (%s)\n", 193*d6b92ffaSHans Petter Selasky CL_STATUS_MSG(status)); 194*d6b92ffaSHans Petter Selasky break; 195*d6b92ffaSHans Petter Selasky } 196*d6b92ffaSHans Petter Selasky max_smps = p_vl->max_wire_smps; 197*d6b92ffaSHans Petter Selasky } 198*d6b92ffaSHans Petter Selasky } 199*d6b92ffaSHans Petter Selasky 200*d6b92ffaSHans Petter Selasky /* 201*d6b92ffaSHans Petter Selasky since we abort immediately when the state != OSM_THREAD_STATE_RUN 202*d6b92ffaSHans Petter Selasky we might have some mads on the queues. After the thread exits 203*d6b92ffaSHans Petter Selasky the vl15 destroy routine should put these mads back... 204*d6b92ffaSHans Petter Selasky */ 205*d6b92ffaSHans Petter Selasky 206*d6b92ffaSHans Petter Selasky OSM_LOG_EXIT(p_vl->p_log); 207*d6b92ffaSHans Petter Selasky } 208*d6b92ffaSHans Petter Selasky 209*d6b92ffaSHans Petter Selasky void osm_vl15_construct(IN osm_vl15_t * p_vl) 210*d6b92ffaSHans Petter Selasky { 211*d6b92ffaSHans Petter Selasky memset(p_vl, 0, sizeof(*p_vl)); 212*d6b92ffaSHans Petter Selasky p_vl->state = OSM_VL15_STATE_INIT; 213*d6b92ffaSHans Petter Selasky p_vl->thread_state = OSM_THREAD_STATE_NONE; 214*d6b92ffaSHans Petter Selasky cl_event_construct(&p_vl->signal); 215*d6b92ffaSHans Petter Selasky cl_spinlock_construct(&p_vl->lock); 216*d6b92ffaSHans Petter Selasky cl_qlist_init(&p_vl->rfifo); 217*d6b92ffaSHans Petter Selasky cl_qlist_init(&p_vl->ufifo); 218*d6b92ffaSHans Petter Selasky cl_thread_construct(&p_vl->poller); 219*d6b92ffaSHans Petter Selasky } 220*d6b92ffaSHans Petter Selasky 221*d6b92ffaSHans Petter Selasky void osm_vl15_destroy(IN osm_vl15_t * p_vl, IN struct osm_mad_pool *p_pool) 222*d6b92ffaSHans Petter Selasky { 223*d6b92ffaSHans Petter Selasky osm_madw_t *p_madw; 224*d6b92ffaSHans Petter Selasky 225*d6b92ffaSHans Petter Selasky OSM_LOG_ENTER(p_vl->p_log); 226*d6b92ffaSHans Petter Selasky 227*d6b92ffaSHans Petter Selasky /* 228*d6b92ffaSHans Petter Selasky Signal our threads that we're leaving. 229*d6b92ffaSHans Petter Selasky */ 230*d6b92ffaSHans Petter Selasky p_vl->thread_state = OSM_THREAD_STATE_EXIT; 231*d6b92ffaSHans Petter Selasky 232*d6b92ffaSHans Petter Selasky /* 233*d6b92ffaSHans Petter Selasky Don't trigger unless event has been initialized. 234*d6b92ffaSHans Petter Selasky Destroy the thread before we tear down the other objects. 235*d6b92ffaSHans Petter Selasky */ 236*d6b92ffaSHans Petter Selasky if (p_vl->state != OSM_VL15_STATE_INIT) 237*d6b92ffaSHans Petter Selasky cl_event_signal(&p_vl->signal); 238*d6b92ffaSHans Petter Selasky 239*d6b92ffaSHans Petter Selasky cl_thread_destroy(&p_vl->poller); 240*d6b92ffaSHans Petter Selasky 241*d6b92ffaSHans Petter Selasky /* 242*d6b92ffaSHans Petter Selasky Return the outstanding messages to the pool 243*d6b92ffaSHans Petter Selasky */ 244*d6b92ffaSHans Petter Selasky 245*d6b92ffaSHans Petter Selasky cl_spinlock_acquire(&p_vl->lock); 246*d6b92ffaSHans Petter Selasky 247*d6b92ffaSHans Petter Selasky while (!cl_is_qlist_empty(&p_vl->rfifo)) { 248*d6b92ffaSHans Petter Selasky p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo); 249*d6b92ffaSHans Petter Selasky osm_mad_pool_put(p_pool, p_madw); 250*d6b92ffaSHans Petter Selasky } 251*d6b92ffaSHans Petter Selasky while (!cl_is_qlist_empty(&p_vl->ufifo)) { 252*d6b92ffaSHans Petter Selasky p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo); 253*d6b92ffaSHans Petter Selasky osm_mad_pool_put(p_pool, p_madw); 254*d6b92ffaSHans Petter Selasky } 255*d6b92ffaSHans Petter Selasky 256*d6b92ffaSHans Petter Selasky cl_spinlock_release(&p_vl->lock); 257*d6b92ffaSHans Petter Selasky 258*d6b92ffaSHans Petter Selasky cl_event_destroy(&p_vl->signal); 259*d6b92ffaSHans Petter Selasky p_vl->state = OSM_VL15_STATE_INIT; 260*d6b92ffaSHans Petter Selasky cl_spinlock_destroy(&p_vl->lock); 261*d6b92ffaSHans Petter Selasky 262*d6b92ffaSHans Petter Selasky OSM_LOG_EXIT(p_vl->p_log); 263*d6b92ffaSHans Petter Selasky } 264*d6b92ffaSHans Petter Selasky 265*d6b92ffaSHans Petter Selasky ib_api_status_t osm_vl15_init(IN osm_vl15_t * p_vl, IN osm_vendor_t * p_vend, 266*d6b92ffaSHans Petter Selasky IN osm_log_t * p_log, IN osm_stats_t * p_stats, 267*d6b92ffaSHans Petter Selasky IN osm_subn_t * p_subn, 268*d6b92ffaSHans Petter Selasky IN int32_t max_wire_smps, 269*d6b92ffaSHans Petter Selasky IN int32_t max_wire_smps2, 270*d6b92ffaSHans Petter Selasky IN uint32_t max_smps_timeout) 271*d6b92ffaSHans Petter Selasky { 272*d6b92ffaSHans Petter Selasky ib_api_status_t status = IB_SUCCESS; 273*d6b92ffaSHans Petter Selasky 274*d6b92ffaSHans Petter Selasky OSM_LOG_ENTER(p_log); 275*d6b92ffaSHans Petter Selasky 276*d6b92ffaSHans Petter Selasky p_vl->p_vend = p_vend; 277*d6b92ffaSHans Petter Selasky p_vl->p_log = p_log; 278*d6b92ffaSHans Petter Selasky p_vl->p_stats = p_stats; 279*d6b92ffaSHans Petter Selasky p_vl->p_subn = p_subn; 280*d6b92ffaSHans Petter Selasky p_vl->max_wire_smps = max_wire_smps; 281*d6b92ffaSHans Petter Selasky p_vl->max_wire_smps2 = max_wire_smps2; 282*d6b92ffaSHans Petter Selasky p_vl->max_smps_timeout = max_wire_smps < max_wire_smps2 ? 283*d6b92ffaSHans Petter Selasky max_smps_timeout : EVENT_NO_TIMEOUT; 284*d6b92ffaSHans Petter Selasky 285*d6b92ffaSHans Petter Selasky status = cl_event_init(&p_vl->signal, FALSE); 286*d6b92ffaSHans Petter Selasky if (status != IB_SUCCESS) 287*d6b92ffaSHans Petter Selasky goto Exit; 288*d6b92ffaSHans Petter Selasky 289*d6b92ffaSHans Petter Selasky p_vl->state = OSM_VL15_STATE_READY; 290*d6b92ffaSHans Petter Selasky 291*d6b92ffaSHans Petter Selasky status = cl_spinlock_init(&p_vl->lock); 292*d6b92ffaSHans Petter Selasky if (status != IB_SUCCESS) 293*d6b92ffaSHans Petter Selasky goto Exit; 294*d6b92ffaSHans Petter Selasky 295*d6b92ffaSHans Petter Selasky /* 296*d6b92ffaSHans Petter Selasky Initialize the thread after all other dependent objects 297*d6b92ffaSHans Petter Selasky have been initialized. 298*d6b92ffaSHans Petter Selasky */ 299*d6b92ffaSHans Petter Selasky status = cl_thread_init(&p_vl->poller, vl15_poller, p_vl, 300*d6b92ffaSHans Petter Selasky "opensm poller"); 301*d6b92ffaSHans Petter Selasky Exit: 302*d6b92ffaSHans Petter Selasky OSM_LOG_EXIT(p_log); 303*d6b92ffaSHans Petter Selasky return status; 304*d6b92ffaSHans Petter Selasky } 305*d6b92ffaSHans Petter Selasky 306*d6b92ffaSHans Petter Selasky void osm_vl15_poll(IN osm_vl15_t * p_vl) 307*d6b92ffaSHans Petter Selasky { 308*d6b92ffaSHans Petter Selasky OSM_LOG_ENTER(p_vl->p_log); 309*d6b92ffaSHans Petter Selasky 310*d6b92ffaSHans Petter Selasky CL_ASSERT(p_vl->state == OSM_VL15_STATE_READY); 311*d6b92ffaSHans Petter Selasky 312*d6b92ffaSHans Petter Selasky /* 313*d6b92ffaSHans Petter Selasky If we have room for more VL15 MADs on the wire, 314*d6b92ffaSHans Petter Selasky then signal the poller thread. 315*d6b92ffaSHans Petter Selasky 316*d6b92ffaSHans Petter Selasky This is not an airtight check, since the poller thread 317*d6b92ffaSHans Petter Selasky could be just about to send another MAD as we signal 318*d6b92ffaSHans Petter Selasky the event here. To cover this rare case, the poller 319*d6b92ffaSHans Petter Selasky thread checks for a spurious wake-up. 320*d6b92ffaSHans Petter Selasky */ 321*d6b92ffaSHans Petter Selasky if (p_vl->p_stats->qp0_mads_outstanding_on_wire < 322*d6b92ffaSHans Petter Selasky (int32_t) p_vl->max_wire_smps) { 323*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, 324*d6b92ffaSHans Petter Selasky "Signalling poller thread\n"); 325*d6b92ffaSHans Petter Selasky cl_event_signal(&p_vl->signal); 326*d6b92ffaSHans Petter Selasky } 327*d6b92ffaSHans Petter Selasky 328*d6b92ffaSHans Petter Selasky OSM_LOG_EXIT(p_vl->p_log); 329*d6b92ffaSHans Petter Selasky } 330*d6b92ffaSHans Petter Selasky 331*d6b92ffaSHans Petter Selasky void osm_vl15_post(IN osm_vl15_t * p_vl, IN osm_madw_t * p_madw) 332*d6b92ffaSHans Petter Selasky { 333*d6b92ffaSHans Petter Selasky OSM_LOG_ENTER(p_vl->p_log); 334*d6b92ffaSHans Petter Selasky 335*d6b92ffaSHans Petter Selasky CL_ASSERT(p_vl->state == OSM_VL15_STATE_READY); 336*d6b92ffaSHans Petter Selasky 337*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, "Posting p_madw = %p\n", p_madw); 338*d6b92ffaSHans Petter Selasky 339*d6b92ffaSHans Petter Selasky /* 340*d6b92ffaSHans Petter Selasky Determine in which fifo to place the pending madw. 341*d6b92ffaSHans Petter Selasky */ 342*d6b92ffaSHans Petter Selasky cl_spinlock_acquire(&p_vl->lock); 343*d6b92ffaSHans Petter Selasky if (p_madw->resp_expected == TRUE) { 344*d6b92ffaSHans Petter Selasky cl_qlist_insert_tail(&p_vl->rfifo, &p_madw->list_item); 345*d6b92ffaSHans Petter Selasky osm_stats_inc_qp0_outstanding(p_vl->p_stats); 346*d6b92ffaSHans Petter Selasky } else 347*d6b92ffaSHans Petter Selasky cl_qlist_insert_tail(&p_vl->ufifo, &p_madw->list_item); 348*d6b92ffaSHans Petter Selasky cl_spinlock_release(&p_vl->lock); 349*d6b92ffaSHans Petter Selasky 350*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, 351*d6b92ffaSHans Petter Selasky "%u QP0 MADs on wire, %u QP0 MADs outstanding\n", 352*d6b92ffaSHans Petter Selasky p_vl->p_stats->qp0_mads_outstanding_on_wire, 353*d6b92ffaSHans Petter Selasky p_vl->p_stats->qp0_mads_outstanding); 354*d6b92ffaSHans Petter Selasky 355*d6b92ffaSHans Petter Selasky osm_vl15_poll(p_vl); 356*d6b92ffaSHans Petter Selasky 357*d6b92ffaSHans Petter Selasky OSM_LOG_EXIT(p_vl->p_log); 358*d6b92ffaSHans Petter Selasky } 359*d6b92ffaSHans Petter Selasky 360*d6b92ffaSHans Petter Selasky void osm_vl15_shutdown(IN osm_vl15_t * p_vl, IN osm_mad_pool_t * p_mad_pool) 361*d6b92ffaSHans Petter Selasky { 362*d6b92ffaSHans Petter Selasky osm_madw_t *p_madw; 363*d6b92ffaSHans Petter Selasky 364*d6b92ffaSHans Petter Selasky OSM_LOG_ENTER(p_vl->p_log); 365*d6b92ffaSHans Petter Selasky 366*d6b92ffaSHans Petter Selasky /* we only should get here after the VL15 interface was initialized */ 367*d6b92ffaSHans Petter Selasky CL_ASSERT(p_vl->state == OSM_VL15_STATE_READY); 368*d6b92ffaSHans Petter Selasky 369*d6b92ffaSHans Petter Selasky /* grab a lock on the object */ 370*d6b92ffaSHans Petter Selasky cl_spinlock_acquire(&p_vl->lock); 371*d6b92ffaSHans Petter Selasky 372*d6b92ffaSHans Petter Selasky /* go over all outstanding MADs and retire their transactions */ 373*d6b92ffaSHans Petter Selasky 374*d6b92ffaSHans Petter Selasky /* first we handle the list of response MADs */ 375*d6b92ffaSHans Petter Selasky p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo); 376*d6b92ffaSHans Petter Selasky while (p_madw != (osm_madw_t *) cl_qlist_end(&p_vl->ufifo)) { 377*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, 378*d6b92ffaSHans Petter Selasky "Releasing Response p_madw = %p\n", p_madw); 379*d6b92ffaSHans Petter Selasky 380*d6b92ffaSHans Petter Selasky osm_mad_pool_put(p_mad_pool, p_madw); 381*d6b92ffaSHans Petter Selasky 382*d6b92ffaSHans Petter Selasky p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo); 383*d6b92ffaSHans Petter Selasky } 384*d6b92ffaSHans Petter Selasky 385*d6b92ffaSHans Petter Selasky /* Request MADs we send out */ 386*d6b92ffaSHans Petter Selasky p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo); 387*d6b92ffaSHans Petter Selasky while (p_madw != (osm_madw_t *) cl_qlist_end(&p_vl->rfifo)) { 388*d6b92ffaSHans Petter Selasky OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, 389*d6b92ffaSHans Petter Selasky "Releasing Request p_madw = %p\n", p_madw); 390*d6b92ffaSHans Petter Selasky 391*d6b92ffaSHans Petter Selasky osm_mad_pool_put(p_mad_pool, p_madw); 392*d6b92ffaSHans Petter Selasky osm_stats_dec_qp0_outstanding(p_vl->p_stats); 393*d6b92ffaSHans Petter Selasky 394*d6b92ffaSHans Petter Selasky p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo); 395*d6b92ffaSHans Petter Selasky } 396*d6b92ffaSHans Petter Selasky 397*d6b92ffaSHans Petter Selasky /* free the lock */ 398*d6b92ffaSHans Petter Selasky cl_spinlock_release(&p_vl->lock); 399*d6b92ffaSHans Petter Selasky 400*d6b92ffaSHans Petter Selasky OSM_LOG_EXIT(p_vl->p_log); 401*d6b92ffaSHans Petter Selasky } 402