On 3/19/2013 9:00 PM, Weiny, Ira wrote:
>> -----Original Message-----
>> From: [email protected] [mailto:linux-rdma-
>> [email protected]] On Behalf Of Hal Rosenstock
>> Sent: Tuesday, March 19, 2013 9:34 AM
>> To: linux-rdma ([email protected])
>> Subject: Re: [PATCH 07/07] opensm/perfmgr: add sl support
>>
>>
>> This doesn't appear to have made it to the list so I'm resending.
>>
>> -------- Original Message --------
>> Subject: Re: [PATCH 07/07] opensm/perfmgr: add sl support
>> Date: Tue, 19 Mar 2013 08:52:04 -0400
>> From: Hal Rosenstock <[email protected]>
>> Reply-To: [email protected] <[email protected]>
>> To: Ira Weiny <[email protected]>, Ira Weiny <[email protected]>
>> CC: Hal Rosenstock <[email protected]>
>>
>> On 2/28/2013 8:09 PM, Ira Weiny wrote:
>>>
>>> SL's are queried internally when running in a master SM
>>
>> Similarly, does PerfMgr really need it's own discovery code when not in
>> standalone mode or could this also be gleaned from existing data SM
>> structures ?
> 
> Yes it could be, however, issuing internal "queries" seemed cleaner.
> 
>>
>>> and queried from the SA when running in a standby or inactive SM.
>>>
>>> Signed-off-by: Ira Weiny <[email protected]>
>>> ---
>>>  include/opensm/osm_perfmgr.h |   11 ++
>>>  opensm/osm_perfmgr.c         |  345
>> +++++++++++++++++++++++++++++++++++++++---
>>>  2 files changed, 336 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/include/opensm/osm_perfmgr.h
>>> b/include/opensm/osm_perfmgr.h index 4141d41..5ca1cf4 100644
>>> --- a/include/opensm/osm_perfmgr.h
>>> +++ b/include/opensm/osm_perfmgr.h
>>> @@ -2,6 +2,7 @@
>>>   * Copyright (c) 2007 The Regents of the University of California.
>>>   * Copyright (c) 2007-2009 Voltaire, Inc. All rights reserved.
>>>   * Copyright (c) 2009,2010 HNR Consulting. All rights reserved.
>>> + * Copyright (c) 2013 Lawrence Livermore National Security, All
>>> + rights reserved
>>>   *
>>>   * This software is available to you under a choice of one of two
>>>   * licenses.  You may choose to be licensed under the terms of the
>>> GNU @@ -90,6 +91,11 @@ typedef enum {
>>>     PERFMGR_SWEEP_SUSPENDED
>>>  } osm_perfmgr_sweep_state_t;
>>>
>>> +typedef struct pr_map_item {
>>> +   cl_map_item_t map_item;
>>> +   ib_path_rec_t pr;
>>> +} pr_map_item_t;
>>> +
>>>  typedef struct monitored_port {
>>>     uint16_t pkey_ix;
>>>     ib_net16_t orig_lid;
>>> @@ -150,6 +156,11 @@ typedef struct osm_perfmgr {
>>>     int16_t local_port;
>>>     int rm_nodes;
>>>     boolean_t query_cpi;
>>> +   cl_qmap_t path_rec_map;
>>
>> Where does cleanup of path_rec_map occur ? Did I miss that ?
> 
> Insert_pr_map will remove entries when new ones with that DLID are added.
> 
> I did not clean up on exit.  I'll add that.
> 
>>
>>> +   /* when operating in stand alone mode we are required to query the
>>> +    * remote master SA */
>>> +   osm_bind_handle_t sa_bind_handle;
>>> +   int pr_query_outstanding;
>>>  } osm_perfmgr_t;
>>>  /*
>>>  * FIELDS
>>> diff --git a/opensm/osm_perfmgr.c b/opensm/osm_perfmgr.c index
>>> 9df28f9..b1cd419 100644
>>> --- a/opensm/osm_perfmgr.c
>>> +++ b/opensm/osm_perfmgr.c
>>> @@ -2,7 +2,7 @@
>>>   * Copyright (c) 2007 The Regents of the University of California.
>>>   * Copyright (c) 2007-2009 Voltaire, Inc. All rights reserved.
>>>   * Copyright (c) 2009,2010 HNR Consulting. All rights reserved.
>>> - * Copyright (c) 2013 Lawrence Livermore National Security. All rights *
>> reserved.
>>> + * Copyright (c) 2013 Lawrence Livermore National Security. All rights
>> reserved.
>>>   *
>>>   * This software is available to you under a choice of one of two
>>>   * licenses.  You may choose to be licensed under the terms of the
>>> GNU @@ -123,6 +123,7 @@ static inline void diff_time(struct timeval
>>> *before, struct timeval *after,  static void
>>> init_monitored_nodes(osm_perfmgr_t * pm)  {
>>>     cl_qmap_init(&pm->monitored_map);
>>> +   cl_qmap_init(&pm->path_rec_map);
>>>     pm->remove_list = NULL;
>>>     cl_event_construct(&pm->sig_query);
>>>     cl_event_init(&pm->sig_query, FALSE); @@ -254,6 +255,10 @@ Exit:
>>>     OSM_LOG_EXIT(pm->log);
>>>  }
>>>
>>> +static void perfmgr_sa_mad_recv_cb(osm_madw_t * p_madw, void
>> *bind_context,
>>> +                           osm_madw_t * p_req_madw);
>>> +static void perfmgr_sa_mad_send_err_cb(void *bind_context,
>>> +                           osm_madw_t * p_madw);
>>>
>> /**********************************************************
>> ************
>>>   * Bind the PerfMgr to the vendor layer for MAD sends/receives
>>>
>>>
>> **********************************************************
>> ************
>>> / @@ -294,6 +299,22 @@ ib_api_status_t
>> osm_perfmgr_bind(osm_perfmgr_t
>>> * pm, ib_net64_t port_guid)
>>>             OSM_LOG(pm->log, OSM_LOG_ERROR,
>>>                     "ERR 5404: Vendor specific bind failed (%s)\n",
>>>                     ib_get_err_str(status));
>>> +           goto Exit;
>>> +   }
>>> +
>>> +   bind_info.mad_class = IB_MCLASS_SUBN_ADM;
>>> +   bind_info.class_version = 2;
>>
>> Are any other bind parameters needed ?
> 
> None that are different from the previous bind.  One could argue for 
> different timeout/retry parameters 
> but we would have to add those to the config file which don't exist now.

OK; I see those parameters set by the existing bind for PerfMgr class.

> 
>>
>>> +
>>> +   pm->sa_bind_handle = osm_vendor_bind(pm->vendor, &bind_info,
>>> +                                        pm->mad_pool,
>>> +                                        perfmgr_sa_mad_recv_cb,
>>> +                                        perfmgr_sa_mad_send_err_cb,
>> pm);
>>
>> Why not only do this when in standalone mode ? Is that due to the bind
>> being needed based on SM state and that isn't known here ?
> 
> Yes.  Also we could be master and then be reduced to standby mode later.  
> The bind is inexpensive and seemed reasonable to just have available 
> regardless of mode.

It's not the expense of the bind that concerns me; it's opening the
unnecessary "door" for additional received MADs that does.

> 
>>
>>> +
>>> +   if (pm->sa_bind_handle == OSM_BIND_INVALID_HANDLE) {
>>> +           status = IB_ERROR;
>>> +           OSM_LOG(pm->log, OSM_LOG_ERROR,
>>> +                   "ERR 540E: PM SA bind failed (%s)\n",
>>> +                   ib_get_err_str(status));
>>>     }
>>>
>>>  Exit:
>>> @@ -307,12 +328,17 @@ Exit:
>>>  static void perfmgr_mad_unbind(osm_perfmgr_t * pm)  {
>>>     OSM_LOG_ENTER(pm->log);
>>> -   if (pm->bind_handle == OSM_BIND_INVALID_HANDLE) {
>>> +
>>> +   if (pm->bind_handle == OSM_BIND_INVALID_HANDLE)
>>>             OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 5405: No
>> previous bind\n");
>>> -           goto Exit;
>>> -   }
>>> -   osm_vendor_unbind(pm->bind_handle);
>>> -Exit:
>>> +   else
>>> +           osm_vendor_unbind(pm->bind_handle);
>>> +
>>> +   if (pm->sa_bind_handle == OSM_BIND_INVALID_HANDLE)
>>> +           OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 540F: No
>> previous SA bind\n");
>>> +   else
>>> +           osm_vendor_unbind(pm->sa_bind_handle);
>>> +
>>>     OSM_LOG_EXIT(pm->log);
>>>  }
>>>
>>> @@ -330,6 +356,250 @@ static ib_net32_t get_qp(monitored_node_t *
>> mon_node, uint8_t port)
>>>     return qp;
>>>  }
>>>
>>> +static inline boolean_t sm_not_active(osm_perfmgr_t *pm) {
>>> +   return (pm->subn->sm_state == IB_SMINFO_STATE_STANDBY ||
>>> +           pm->subn->sm_state == IB_SMINFO_STATE_NOTACTIVE); }
>>> +
>>> +static int get_sm_info(osm_perfmgr_t *pm, ib_net16_t *smlid, uint8_t
>>> +*smsl) {
>>> +   int i, rc = -1;
>>> +   uint32_t num_ports = 32;
>>> +   ib_port_attr_t attr_array[32];
>>
>> 64 is better as there are 36 port switches. Also, this should be a define.
> 
> Agreed.  However, in the case of a switch the PM should be running on port 0 
> only right?

Yes, in the case of a switch, PM could run on port 0.

>>
>>> +
>>> +   osm_vendor_get_all_port_attr(pm->vendor, attr_array,
>> &num_ports);
>>> +
>>> +   for(i = 0; i<num_ports; i++) {
>>> +           if (attr_array[i].port_guid == pm->port_guid) {
>>> +                   *smlid = attr_array[i].sm_lid;
>>> +                   *smsl = attr_array[i].sm_sl;
>>> +                   rc = 0;
>>> +           }
>>> +   }
>>> +
>>> +   return (rc);
>>> +}
>>> +
>>> +static void insert_pr_map(osm_perfmgr_t *pm,  ib_path_rec_t *pr) {
>>> +   pr_map_item_t *mi = calloc(1, sizeof(*mi));
>>> +   if (mi) {
>>> +           cl_map_item_t *tmp;
>>> +           if ((tmp = cl_qmap_get(&pm->path_rec_map, (uint64_t)pr-
>>> dlid))
>>> +                           != cl_qmap_end(&pm->path_rec_map)) {
>>> +                   cl_qmap_remove_item(&pm->path_rec_map, tmp);
>>> +                   free(tmp);
>>> +           }
>>> +           memcpy(&mi->pr, pr, sizeof(mi->pr));
>>> +           cl_qmap_insert(&pm->path_rec_map, (uint64_t)pr->dlid,
>>> +                  (cl_map_item_t *) mi);
>>> +   } else {
>>> +           OSM_LOG(pm->log, OSM_LOG_ERROR,
>>> +                   "ERR 54FC: Failed to allocate path "
>>> +                   "record map item for DLID %d",
>>
>> LIDs should be formatted as %u
> 
> Ok.
> 
>>
>>> +                   cl_ntoh16(pr->dlid));
>>> +   }
>>> +}
>>> +
>>> +/**
>>>
>> +=========================================================
>> ============
>>> +====
>>> + * SA query call backs for the sa_bind_handle  */ static void
>>> +perfmgr_sa_mad_recv_cb(osm_madw_t * p_madw, void *bind_context,
>>> +                              osm_madw_t * p_req_madw)
>>> +{
>>> +   osm_perfmgr_t *pm = (osm_perfmgr_t *) bind_context;
>>> +   ib_sa_mad_t *sa_mad;
>>> +   int num_results;
>>> +   int i;
>>> +
>>> +   OSM_LOG_ENTER(pm->log);
>>> +
>>> +   osm_madw_copy_context(p_madw, p_req_madw);
>>> +   osm_mad_pool_put(pm->mad_pool, p_req_madw);
>>> +
>>> +   sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
>>> +
>>> +   num_results = (p_madw->mad_size - IB_SA_MAD_HDR_SIZE) /
>>> +                           (sa_mad->attr_offset << 3);
>>> +
>>> +   for (i = 0; i < num_results; i++) {
>>> +           ib_path_rec_t *pr = (ib_path_rec_t *)
>>> +                           (sa_mad->data + (i*sizeof(ib_path_rec_t)));
>>> +
>>> +           /* only want reversible paths */
>>> +           if ((pr->num_path & 0x80) == 0)
>>
>> Shouldn't this just be part of the query and wouldn't need checking here ?
> 
> Yea that would be better.
> 
>>
>>> +                   continue;
>>> +
>>> +           insert_pr_map(pm, pr);
>>> +   }
>>> +
>>> +   osm_mad_pool_put(pm->mad_pool, p_madw);
>>> +   pm->pr_query_outstanding = 0;
>>> +
>>> +   OSM_LOG_EXIT(pm->log);
>>> +}
>>> +
>>> +static void perfmgr_sa_mad_send_err_cb(void *bind_context,
>> osm_madw_t
>>> +* p_madw) {
>>> +   osm_perfmgr_t *pm = (osm_perfmgr_t *) bind_context;
>>> +   OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 540D: PM PathRecord
>> query "
>>> +           "failed; sm LID %u MAD TID 0x%" PRIx64 "\n",
>>> +           cl_ntoh16(p_madw->mad_addr.dest_lid),
>>> +           cl_ntoh64(p_madw->p_mad->trans_id));
>>> +   pm->pr_query_outstanding = -1;
>>> +}
>>> +
>>> +static void create_half_world_query(osm_perfmgr_t *pm, ib_sa_mad_t
>>> +*sa_mad) {
>>> +   ib_path_rec_t *pr = (ib_path_rec_t *)sa_mad->data;
>>> +
>>> +   sa_mad->base_ver = 1;
>>> +   sa_mad->mgmt_class = IB_MCLASS_SUBN_ADM;
>>> +   sa_mad->class_ver = 2;
>>> +   sa_mad->method = IB_MAD_METHOD_GETTABLE;
>>> +   sa_mad->status = 0;
>>> +   sa_mad->trans_id =
>>> +       cl_hton64((uint64_t) cl_atomic_inc(&pm->trans_id) &
>>> +                 (uint64_t) (0xFFFFFFFF));
>>> +   if (sa_mad->trans_id == 0)
>>> +           sa_mad->trans_id =
>>> +               cl_hton64((uint64_t) cl_atomic_inc(&pm->trans_id) &
>>> +                         (uint64_t) (0xFFFFFFFF));
>>> +   sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD;
>>> +   sa_mad->attr_mod = 0;
>>> +
>>> +   pr->slid = osm_port_get_base_lid(osm_get_port_by_guid(pm-
>>> subn,
>>> +                                                   pm->port_guid));
>>> +   sa_mad->comp_mask = IB_PR_COMPMASK_SLID;
>>
>> Although OpenSM supports this, it would be best to have this as compliant
>> query which requires NumbPath and SGID. Also, previously discussed adding
>> in Reversible.
> 
> Agreed.
> 
>>
>>> +}
>>> +
>>> +static int send_sa_pr_query(osm_perfmgr_t *pm) {
>>> +   ib_sa_mad_t *sa_mad = NULL;
>>> +   osm_madw_t *p_madw = NULL;
>>> +   ib_net16_t smlid;
>>> +   uint8_t smsl;
>>> +
>>> +   if (get_sm_info(pm, &smlid, &smsl) < 0) {
>>> +           OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 54FE: "
>>> +                   "PM failed to find SM LID & SL for PR query\n");
>>> +           return (-1);
>>> +   }
>>> +
>>> +   p_madw = osm_mad_pool_get(pm->mad_pool, pm-
>>> sa_bind_handle,
>>> +                             MAD_BLOCK_SIZE, NULL);
>>> +   if (p_madw == NULL)
>>> +           return -1;
>>> +
>>> +   sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
>>> +
>>> +   create_half_world_query(pm, sa_mad);
>>> +
>>> +   p_madw->mad_addr.dest_lid = smlid;
>>> +   p_madw->mad_addr.addr_type.gsi.remote_qp = 1;
>>> +   p_madw->mad_addr.addr_type.gsi.remote_qkey =
>>> +       cl_hton32(IB_QP1_WELL_KNOWN_Q_KEY);
>>> +   p_madw->mad_addr.addr_type.gsi.pkey_ix = 0;
>>> +   p_madw->mad_addr.addr_type.gsi.service_level = smsl;
>>> +   p_madw->mad_addr.addr_type.gsi.global_route = FALSE;
>>> +   p_madw->resp_expected = TRUE;
>>> +
>>> +   if (osm_vendor_send(pm->sa_bind_handle, p_madw, TRUE)
>>> +       != IB_SUCCESS)
>>> +           return (-1);
>>> +
>>> +   return (0);
>>> +}
>>> +
>>> +static int get_internal_pr(osm_perfmgr_t *pm) {
>>> +   ib_sa_mad_t sa_mad;
>>> +   const osm_alias_guid_t *p_src_alias_guid, *p_dest_alias_guid;
>>> +   const osm_port_t *p_src_port, *p_dest_port;
>>> +   const ib_gid_t *p_sgid = NULL, *p_dgid = NULL;
>>> +   osm_port_t *p_local_port;
>>> +   cl_qlist_t pr_list;
>>> +   cl_list_item_t *item;
>>> +   unsigned num_rec, i;
>>> +
>>> +   create_half_world_query(pm, &sa_mad);
>>> +
>>
>> Doesn't the SMDB RO lock needs to be held here or is it already held when
>> reaching here ?
> 
> Yes, I think so.  I think I had it locked around get_internal_pr in a 
> previous version but it is not now.  So yes.
> 
>>
>>> +   osm_pr_get_end_points(&pm->osm->sa, &sa_mad,
>>> +                   &p_src_alias_guid, &p_dest_alias_guid,
>>> +                   &p_src_port, &p_dest_port,
>>> +                   &p_sgid, &p_dgid);
>>> +
>>> +   cl_qlist_init(&pr_list);
>>> +   p_local_port = osm_get_port_by_guid(pm->subn, pm->port_guid);
>>> +
>>> +   /* Get all alias GUIDs for the src port */
>>> +   p_src_alias_guid = (osm_alias_guid_t *) cl_qmap_head(&pm->subn-
>>> alias_port_guid_tbl);
>>> +   while (p_src_alias_guid !=
>>> +          (osm_alias_guid_t *)
>>> +cl_qmap_end(&pm->subn->alias_port_guid_tbl)) {
>>> +
>>> +           if (osm_get_port_by_alias_guid(pm->subn,
>> p_src_alias_guid->alias_guid)
>>> +               == p_src_port) {
>>
>> Only base port GUIDs need checking.
> 
> So you just need this?
> 
>       osm_pr_process_half(&pm->osm->sa, &sa_mad, p_local_port,
>                                               p_src_alias_guid,
>                                               p_dest_alias_guid,
>                                               p_sgid, p_dgid, &pr_list);
> 
> No loop?

A loop is needed to filter the response and only use the base port GUIDs.

>>
>>> +                   osm_pr_process_half(&pm->osm->sa, &sa_mad,
>> p_local_port,
>>> +                                           p_src_alias_guid,
>> p_dest_alias_guid,
>>> +                                           p_sgid, p_dgid, &pr_list);
>>> +           }
>>> +
>>> +           p_src_alias_guid = (osm_alias_guid_t *)
>> cl_qmap_next(&p_src_alias_guid->map_item);
>>> +   }
>>> +
>>
>> SMDB RO lock would be released here if it's grabbed above.
> 
> Yes
> 
>>
>>> +   num_rec = cl_qlist_count(&pr_list);
>>> +   for (i = 0; i < num_rec; i++) {
>>> +           ib_path_rec_t *pr;
>>> +           item = cl_qlist_remove_head(&pr_list);
>>> +           pr = (ib_path_rec_t *)((osm_sa_item_t *)item)->resp.data;
>>> +
>>> +           /* only want reversible paths */
>>> +           if ((pr->num_path & 0x80) == 0)
>>> +                   continue;
>>> +
>>> +           insert_pr_map(pm, pr);
>>> +           free(item);
>>> +   }
>>> +   pm->pr_query_outstanding = 0;
>>> +   return (0);
>>> +}
>>> +
>>> +static ib_path_rec_t * get_pr_from_pr_map(osm_perfmgr_t *pm,
>>> +ib_net16_t dlid) {
>>> +   cl_map_item_t *mi;
>>> +   if ((mi = cl_qmap_get(&pm->path_rec_map, (uint64_t)dlid)) !=
>>> +        cl_qmap_end(&pm->path_rec_map)) {
>>> +           pr_map_item_t *pr = (pr_map_item_t *)mi;
>>> +           return (&pr->pr);
>>> +   }
>>> +   return (NULL);
>>> +}
>>> +
>>> +static int8_t get_sl(osm_perfmgr_t *pm, monitored_node_t *
>> mon_node,
>>> +uint8_t port) {
>>> +   uint16_t dlid;
>>> +   ib_path_rec_t *pr;
>>> +
>>> +   if (!mon_node || port >= mon_node->num_ports)
>>> +           return (-1);
>>> +
>>> +   dlid = mon_node->port[port].redirection ?
>>> +                           mon_node->port[port].lid :
>>> +                           mon_node->port[port].orig_lid;
>>> +   pr = get_pr_from_pr_map(pm, dlid);
>>> +   if (pr) {
>>> +           OSM_LOG(pm->log, OSM_LOG_DEBUG, "PM %s port %d ->
>> SL 0x%x\n",
>>> +                   mon_node->name, port, ib_path_rec_sl(pr));
>>> +           return ((int8_t)ib_path_rec_sl(pr));
>>> +   }
>>> +
>>> +   OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 54FD: "
>>> +           "PM failed to find SL for %s port %d\n",
>>> +           mon_node->name, port);
>>> +   return (-1);
>>> +}
>>> +
>>>  static ib_net16_t get_base_lid(osm_node_t * p_node, uint8_t port)  {
>>>     switch (p_node->node_info.node_type) { @@ -683,6 +953,7 @@
>> static
>>> void perfmgr_query_counters(cl_map_item_t * p_map_item, void
>> *context)
>>>     /* issue the query for each port */
>>>     for (port = mon_node->esp0 ? 0 : 1; port < num_ports; port++) {
>>>             ib_net16_t lid;
>>> +           int8_t sl;
>>>
>>>             if (!osm_node_get_physp_ptr(node, port))
>>>                     continue;
>>> @@ -700,6 +971,9 @@ static void perfmgr_query_counters(cl_map_item_t
>> * p_map_item, void *context)
>>>             }
>>>
>>>             remote_qp = get_qp(mon_node, port);
>>> +           sl = get_sl(pm, mon_node, port);
>>> +           if (sl < 0)
>>> +                   continue;
>>>
>>>             mad_context.perfmgr_context.node_guid = node_guid;
>>>             mad_context.perfmgr_context.port = port; @@ -709,7
>> +983,7 @@ static
>>> void perfmgr_query_counters(cl_map_item_t * p_map_item, void
>> *context)
>>>                     status = perfmgr_send_cpi_mad(pm, lid, remote_qp,
>>>                                             mon_node-
>>> port[port].pkey_ix,
>>>                                             port, &mad_context,
>>> -                                           0); /* FIXME SL != 0 */
>>> +                                           sl);
>>>                     if (status != IB_SUCCESS)
>>>                             OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR
>> 5410: "
>>>                                     "Failed to issue ClassPortInfo query "
>>> @@ -733,7 +1007,7 @@ static void
>> perfmgr_query_counters(cl_map_item_t * p_map_item, void *context)
>>>                                                  port,
>> IB_MAD_METHOD_GET,
>>>                                                  0xffff,
>>>                                                  &mad_context,
>>> -                                                0); /* FIXME SL != 0 */
>>> +                                                sl);
>>>                     if (status != IB_SUCCESS)
>>>                             OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR
>> 5409: "
>>>                                     "Failed to issue port counter query
>> for node 0x%"
>>> @@ -751,7 +1025,7 @@ static void
>> perfmgr_query_counters(cl_map_item_t * p_map_item, void *context)
>>>                                                           port,
>>>
>> IB_MAD_METHOD_GET,
>>>                                                           &mad_context,
>>> -                                                         0); /* FIXME SL !=
>> 0 */
>>> +                                                         sl);
>>>                             if (status != IB_SUCCESS)
>>>                                     OSM_LOG(pm->log,
>> OSM_LOG_ERROR,
>>>                                             "ERR 5417: Failed to issue "
>>> @@ -1007,8 +1281,7 @@ void osm_perfmgr_process(osm_perfmgr_t *
>> pm)
>>>     pm->sweep_state = PERFMGR_SWEEP_ACTIVE;
>>>     cl_spinlock_release(&pm->lock);
>>>
>>> -   if (pm->subn->sm_state == IB_SMINFO_STATE_STANDBY ||
>>> -       pm->subn->sm_state == IB_SMINFO_STATE_NOTACTIVE)
>>> +   if (sm_not_active(pm))
>>>             perfmgr_discovery(pm->subn->p_osm);
>>>
>>>     /* if redirection enabled, determine local port */ @@ -1034,6
>>> +1307,18 @@ void osm_perfmgr_process(osm_perfmgr_t * pm)  #ifdef
>>> ENABLE_OSM_PERF_MGR_PROFILE
>>>     gettimeofday(&before, NULL);
>>>  #endif
>>> +   pm->pr_query_outstanding = 1;
>>> +   if (sm_not_active(pm)) {
>>> +           /* FIXME register for UnPath/RePath rather than reissue
>> query */
>>> +           if (send_sa_pr_query(pm)) {
>>> +                   OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 542F: "
>>> +                                   "PM PathRecord query send
>> failed\n");
>>> +                   pm->pr_query_outstanding = -1;
>>> +           }
>>> +   } else {
>>> +           get_internal_pr(pm);
>>> +   }
>>> +
>>>     /* With the global lock held, collect the node guids */
>>>     /* FIXME we should be able to track SA notices
>>>      * and not have to sweep the node_guid_tbl each pass @@ -1043,8
>>> +1328,15 @@ void osm_perfmgr_process(osm_perfmgr_t * pm)
>>>     cl_qmap_apply_func(&pm->subn->node_guid_tbl, collect_guids,
>> pm);
>>>     cl_plock_release(&pm->osm->lock);
>>>
>>> -   /* then for each node query their counters */
>>> -   cl_qmap_apply_func(&pm->monitored_map,
>> perfmgr_query_counters, pm);
>>> +   /* Wait for PR query to complete */
>>> +   while(pm->pr_query_outstanding == 1)
>>> +           ;
>>
>> A better way to wait for PR response/timeout should be used.
> 
> What is most concerning, the fear of an endless loop, or the busy waiting?

I was concerned with the busy waiting.

> In the former the vendor mad layer would have to fail.  
> For the later we could add sleeps but that seemed inefficient.
> Adding another timer also seems like a waste since in the stand alone mode we 
> are simply waiting for the query to return and in the integrated mode this is 
> effectively a no-op.

In standalone mode, aren't there still other threads ? While this thread
is busy waiting, what are the other threads doing ?

-- Hal

> Ira
> 
>>
>> -- Hal
>>
>>> +
>>> +   if (pm->pr_query_outstanding == 0) {
>>> +           cl_qmap_apply_func(&pm->monitored_map,
>> perfmgr_query_counters, pm);
>>> +   } else {
>>> +           pm->pr_query_outstanding = 0;
>>> +   }
>>>
>>>     /* clean out any nodes found to be removed during the sweep */
>>>     remove_marked_nodes(pm);
>>> @@ -1235,6 +1527,7 @@ static void
>> perfmgr_check_overflow(osm_perfmgr_t * pm,
>>>          counter_overflow_32(pc->rcv_pkts)))) {
>>>             osm_node_t *p_node = NULL;
>>>             ib_net16_t lid = 0;
>>> +           int8_t sl;
>>>
>>>             if (!mon_node->port[port].valid)
>>>                     goto Exit;
>>> @@ -1244,6 +1537,9 @@ static void
>> perfmgr_check_overflow(osm_perfmgr_t * pm,
>>>                        ") port %d; clearing counters\n",
>>>                        mon_node->name, mon_node->guid, port);
>>>
>>> +           if ((sl = get_sl(pm, mon_node, port)) < 0)
>>> +                   goto Exit;
>>> +
>>>             cl_plock_acquire(&pm->osm->lock);
>>>             p_node =
>>>                 osm_get_node_by_guid(pm->subn,
>> cl_hton64(mon_node->guid)); @@
>>> -1276,8 +1572,7 @@ static void perfmgr_check_overflow(osm_perfmgr_t *
>> pm,
>>>             status = perfmgr_send_pc_mad(pm, lid, remote_qp,
>> pkey_ix,
>>>                                          port, IB_MAD_METHOD_SET,
>>>                                          counter_select,
>>> -                                        &mad_context,
>>> -                                        0); /* FIXME SL != 0 */
>>> +                                        &mad_context, sl);
>>>             if (status != IB_SUCCESS)
>>>                     OSM_LOG(pm->log, OSM_LOG_ERROR, "PerfMgr:
>> ERR 5411: "
>>>                             "Failed to send clear counters MAD for %s
>> (0x%"
>>> @@ -1320,6 +1615,7 @@ static void
>> perfmgr_check_pce_overflow(osm_perfmgr_t * pm,
>>>         counter_overflow_64(pc->multicast_rcv_pkts)))) {
>>>             osm_node_t *p_node = NULL;
>>>             ib_net16_t lid = 0;
>>> +           int8_t sl;
>>>
>>>             if (!mon_node->port[port].valid)
>>>                     goto Exit;
>>> @@ -1329,6 +1625,9 @@ static void
>> perfmgr_check_pce_overflow(osm_perfmgr_t * pm,
>>>                     PRIx64 ") port %d; clearing counters\n",
>>>                     mon_node->name, mon_node->guid, port);
>>>
>>> +           if ((sl = get_sl(pm, mon_node, port)) < 0)
>>> +                   goto Exit;
>>> +
>>>             cl_plock_acquire(&pm->osm->lock);
>>>             p_node =
>>>                 osm_get_node_by_guid(pm->subn,
>> cl_hton64(mon_node->guid)); @@
>>> -1350,8 +1649,7 @@ static void
>> perfmgr_check_pce_overflow(osm_perfmgr_t * pm,
>>>             /* clear port counters */
>>>             status = perfmgr_send_pce_mad(pm, lid, remote_qp,
>> pkey_ix,
>>>                                           port, IB_MAD_METHOD_SET,
>>> -                                         &mad_context,
>>> -                                         0); /* FIXME SL != 0 */
>>> +                                         &mad_context, sl);
>>>             if (status != IB_SUCCESS)
>>>                     OSM_LOG(pm->log, OSM_LOG_ERROR, "PerfMgr:
>> ERR 5419: "
>>>                             "Failed to send clear counters MAD for %s
>> (0x%"
>>> @@ -1475,6 +1773,7 @@ static boolean_t handle_redirect(osm_perfmgr_t
>> *pm,
>>>     boolean_t valid = TRUE;
>>>     int16_t pkey_ix = 0;
>>>     uint8_t mad_method;
>>> +   int8_t sl;
>>>
>>>     OSM_LOG(pm->log, OSM_LOG_VERBOSE,
>>>             "Redirection to LID %u GID %s QP 0x%x received\n", @@ -
>> 1528,6
>>> +1827,12 @@ static boolean_t handle_redirect(osm_perfmgr_t *pm,
>>>     if (!valid)
>>>             goto Exit;
>>>
>>> +   sl = get_sl(pm, p_mon_node, port);
>>> +   if (sl < 0) {
>>> +           valid = FALSE;
>>> +           goto Exit;
>>> +   }
>>> +
>>>     /* LID redirection support (easier than GID redirection) */
>>>     cl_plock_acquire(&pm->osm->lock);
>>>     p_mon_node->port[port].redirection = TRUE; @@ -1550,7 +1855,7
>> @@
>>> static boolean_t handle_redirect(osm_perfmgr_t *pm,
>>>             status = perfmgr_send_cpi_mad(pm, cpi->redir_lid,
>>>                                             cpi->redir_qp, pkey_ix,
>>>                                             port, mad_context,
>>> -                                           0); /* FIXME SL != 0 */
>>> +                                           sl);
>>>     } else {
>>>             /* reissue the original query to the redirected location */
>>>             mad_method = mad_context-
>>> perfmgr_context.mad_method;
>>> @@ -1561,14 +1866,14 @@ static boolean_t
>> handle_redirect(osm_perfmgr_t *pm,
>>>                                                  mad_method,
>>>                                                  0xffff,
>>>                                                  mad_context,
>>> -                                                0); /* FIXME SL != 0 */
>>> +                                                sl);
>>>             } else {
>>>                     status = perfmgr_send_pce_mad(pm, cpi->redir_lid,
>>>                                                   cpi->redir_qp,
>>>                                                   pkey_ix, port,
>>>                                                   mad_method,
>>>                                                   mad_context,
>>> -                                                 0); /* FIXME SL != 0 */
>>> +                                                 sl);
>>>             }
>>>     }
>>>     if (status != IB_SUCCESS)
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the
>> body of a message to [email protected] More majordomo info at
>> http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to