2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 * Declaration of osm_sm_t.
39 * This object represents an IBA subnet.
40 * This object is part of the OpenSM family of objects.
46 #include <iba/ib_types.h>
47 #include <complib/cl_passivelock.h>
48 #include <complib/cl_event.h>
49 #include <complib/cl_thread.h>
50 #include <complib/cl_dispatcher.h>
51 #include <complib/cl_event_wheel.h>
52 #include <vendor/osm_vendor_api.h>
53 #include <opensm/osm_stats.h>
54 #include <opensm/osm_subnet.h>
55 #include <opensm/osm_vl15intf.h>
56 #include <opensm/osm_mad_pool.h>
57 #include <opensm/osm_log.h>
58 #include <opensm/osm_sm_mad_ctrl.h>
59 #include <opensm/osm_lid_mgr.h>
60 #include <opensm/osm_ucast_mgr.h>
61 #include <opensm/osm_port.h>
62 #include <opensm/osm_db.h>
63 #include <opensm/osm_remote_sm.h>
66 # define BEGIN_C_DECLS extern "C" {
67 # define END_C_DECLS }
68 #else /* !__cplusplus */
69 # define BEGIN_C_DECLS
71 #endif /* __cplusplus */
79 * The SM object encapsulates the information needed by the
80 * OpenSM to instantiate a subnet manager. The OpenSM allocates
81 * one SM object per subnet manager.
83 * The SM object is thread safe.
85 * This object should be treated as opaque and should
86 * be manipulated only through the provided functions.
92 /****s* OpenSM: SM/osm_sm_t
97 * Subnet Manager structure.
99 * This object should be treated as opaque and should
100 * be manipulated only through the provided functions.
104 typedef struct osm_sm {
105 osm_thread_state_t thread_state;
106 unsigned signal_mask;
107 cl_spinlock_t signal_lock;
108 cl_spinlock_t state_lock;
109 cl_event_t signal_event;
110 cl_event_t subnet_up_event;
111 cl_timer_t sweep_timer;
112 cl_timer_t polling_timer;
113 cl_event_wheel_t trap_aging_tracker;
115 unsigned master_sm_found;
116 uint32_t retry_number;
117 ib_net64_t master_sm_guid;
118 osm_remote_sm_t *p_polling_sm;
121 osm_vendor_t *p_vendor;
123 osm_mad_pool_t *p_mad_pool;
125 cl_dispatcher_t *p_disp;
127 atomic32_t sm_trans_id;
128 cl_spinlock_t mgrp_lock;
129 cl_qlist_t mgrp_list;
130 osm_sm_mad_ctrl_t mad_ctrl;
131 osm_lid_mgr_t lid_mgr;
132 osm_ucast_mgr_t ucast_mgr;
133 cl_disp_reg_handle_t sweep_fail_disp_h;
134 cl_disp_reg_handle_t ni_disp_h;
135 cl_disp_reg_handle_t pi_disp_h;
136 cl_disp_reg_handle_t nd_disp_h;
137 cl_disp_reg_handle_t si_disp_h;
138 cl_disp_reg_handle_t lft_disp_h;
139 cl_disp_reg_handle_t mft_disp_h;
140 cl_disp_reg_handle_t sm_info_disp_h;
141 cl_disp_reg_handle_t trap_disp_h;
142 cl_disp_reg_handle_t slvl_disp_h;
143 cl_disp_reg_handle_t vla_disp_h;
144 cl_disp_reg_handle_t pkey_disp_h;
149 * Pointer to the Subnet object for this subnet.
152 * Pointer to the database (persistency) object
155 * Pointer to the vendor specific interfaces object.
158 * Pointer to the log object.
161 * Pointer to the MAD pool.
164 * Pointer to the VL15 interface.
170 * Pointer to the Dispatcher.
173 * Pointer to the serializing lock.
179 /****f* OpenSM: SM/osm_sm_construct
184 * This function constructs an SM object.
188 void osm_sm_construct(IN osm_sm_t * const p_sm);
192 * [in] Pointer to a SM object to construct.
195 * This function does not return a value.
198 * Allows calling osm_sm_init, osm_sm_destroy
200 * Calling osm_sm_construct is a prerequisite to calling any other
201 * method except osm_sm_init.
204 * SM object, osm_sm_init, osm_sm_destroy
207 /****f* OpenSM: SM/osm_sm_shutdown
212 * The osm_sm_shutdown function shutdowns an SM, stopping the sweeper
213 * and unregistering all messages from the dispatcher
217 void osm_sm_shutdown(IN osm_sm_t * const p_sm);
221 * [in] Pointer to a SM object to shutdown.
224 * This function does not return a value.
227 * SM object, osm_sm_construct, osm_sm_init
230 /****f* OpenSM: SM/osm_sm_destroy
235 * The osm_sm_destroy function destroys an SM, releasing
240 void osm_sm_destroy(IN osm_sm_t * const p_sm);
244 * [in] Pointer to a SM object to destroy.
247 * This function does not return a value.
250 * Performs any necessary cleanup of the specified SM object.
251 * Further operations should not be attempted on the destroyed object.
252 * This function should only be called after a call to osm_sm_construct or
256 * SM object, osm_sm_construct, osm_sm_init
259 /****f* OpenSM: SM/osm_sm_init
264 * The osm_sm_init function initializes a SM object for use.
269 osm_sm_init(IN osm_sm_t * const p_sm,
270 IN osm_subn_t * const p_subn,
271 IN osm_db_t * const p_db,
272 IN osm_vendor_t * const p_vendor,
273 IN osm_mad_pool_t * const p_mad_pool,
274 IN osm_vl15_t * const p_vl15,
275 IN osm_log_t * const p_log,
276 IN osm_stats_t * const p_stats,
277 IN cl_dispatcher_t * const p_disp, IN cl_plock_t * const p_lock);
281 * [in] Pointer to an osm_sm_t object to initialize.
284 * [in] Pointer to the Subnet object for this subnet.
287 * [in] Pointer to the vendor specific interfaces object.
290 * [in] Pointer to the MAD pool.
293 * [in] Pointer to the VL15 interface.
296 * [in] Pointer to the log object.
299 * [in] Pointer to the statistics object.
302 * [in] Pointer to the OpenSM central Dispatcher.
305 * [in] Pointer to the OpenSM serializing lock.
308 * IB_SUCCESS if the SM object was initialized successfully.
311 * Allows calling other SM methods.
314 * SM object, osm_sm_construct, osm_sm_destroy
317 /****f* OpenSM: SM/osm_sm_signal
326 void osm_sm_signal(IN osm_sm_t * const p_sm, osm_signal_t signal);
330 * [in] Pointer to an osm_sm_t object.
333 * [in] sm signal number.
341 /****f* OpenSM: SM/osm_sm_sweep
346 * Initiates a subnet sweep.
350 void osm_sm_sweep(IN osm_sm_t * const p_sm);
354 * [in] Pointer to an osm_sm_t object.
357 * IB_SUCCESS if the sweep completed successfully.
365 /****f* OpenSM: SM/osm_sm_bind
370 * Binds the sm object to a port guid.
375 osm_sm_bind(IN osm_sm_t * const p_sm, IN const ib_net64_t port_guid);
379 * [in] Pointer to an osm_sm_t object to bind.
382 * [in] Local port GUID with which to bind.
389 * A given SM object can only be bound to one port at a time.
394 /****f* OpenSM: SM/osm_req_get
399 * Starts the process to transmit a directed route request for
405 osm_req_get(IN osm_sm_t * sm,
406 IN const osm_dr_path_t * const p_path,
407 IN const uint16_t attr_id,
408 IN const uint32_t attr_mod,
409 IN const cl_disp_msgid_t err_msg,
410 IN const osm_madw_context_t * const p_context);
414 * [in] Pointer to an osm_sm_t object.
417 * [in] Pointer to the directed route path to the node
418 * from which to retrieve the attribute.
421 * [in] Attribute ID to request.
424 * [in] Attribute modifier for this request.
427 * [in] Message id with which to post this MAD if an error occurs.
430 * [in] Mad wrapper context structure to be copied into the wrapper
431 * context, and thus visible to the recipient of the response.
434 * IB_SUCCESS if the request was successful.
437 * This function asynchronously requests the specified attribute.
438 * The response from the node will be routed through the Dispatcher
439 * to the appropriate receive controller object.
441 /****f* OpenSM: SM/osm_req_set
446 * Starts the process to transmit a directed route Set() request.
451 osm_req_set(IN osm_sm_t * sm,
452 IN const osm_dr_path_t * const p_path,
453 IN const uint8_t * const p_payload,
454 IN const size_t payload_size,
455 IN const uint16_t attr_id,
456 IN const uint32_t attr_mod,
457 IN const cl_disp_msgid_t err_msg,
458 IN const osm_madw_context_t * const p_context);
462 * [in] Pointer to an osm_sm_t object.
465 * [in] Pointer to the directed route path of the recipient.
468 * [in] Pointer to the SMP payload to send.
471 * [in] The size of the payload to be copied to the SMP data field.
474 * [in] Attribute ID to request.
477 * [in] Attribute modifier for this request.
480 * [in] Message id with which to post this MAD if an error occurs.
483 * [in] Mad wrapper context structure to be copied into the wrapper
484 * context, and thus visible to the recipient of the response.
487 * IB_SUCCESS if the request was successful.
490 * This function asynchronously requests the specified attribute.
491 * The response from the node will be routed through the Dispatcher
492 * to the appropriate receive controller object.
494 /****f* OpenSM: SM/osm_resp_send
499 * Starts the process to transmit a directed route response.
504 osm_resp_send(IN osm_sm_t * sm,
505 IN const osm_madw_t * const p_req_madw,
506 IN const ib_net16_t status, IN const uint8_t * const p_payload);
510 * [in] Pointer to an osm_resp_t object.
513 * [in] Pointer to the MAD Wrapper object for the requesting MAD
514 * to which this response is generated.
517 * [in] Status for this response.
520 * [in] Pointer to the payload of the response MAD.
523 * IB_SUCCESS if the response was successful.
527 /****f* OpenSM: SM/osm_sm_mcgrp_join
532 * Adds a port to the multicast group. Creates the multicast group
535 * This function is called by the SA.
540 osm_sm_mcgrp_join(IN osm_sm_t * const p_sm,
541 IN const ib_net16_t mlid,
542 IN const ib_net64_t port_guid,
543 IN osm_mcast_req_type_t req_type);
547 * [in] Pointer to an osm_sm_t object.
553 * [in] Port GUID to add to the group.
556 * [in] Type of the MC request that caused this join
567 /****f* OpenSM: SM/osm_sm_mcgrp_leave
572 * Removes a port from the multicast group.
574 * This function is called by the SA.
579 osm_sm_mcgrp_leave(IN osm_sm_t * const p_sm,
580 IN const ib_net16_t mlid, IN const ib_net64_t port_guid);
584 * [in] Pointer to an osm_sm_t object.
590 * [in] Port GUID to remove from the group.
600 /****f* OpenSM: OpenSM/osm_sm_wait_for_subnet_up
602 * osm_sm_wait_for_subnet_up
605 * Blocks the calling thread until the subnet is up.
609 static inline cl_status_t
610 osm_sm_wait_for_subnet_up(IN osm_sm_t * const p_sm,
611 IN uint32_t const wait_us,
612 IN boolean_t const interruptible)
614 return (cl_event_wait_on(&p_sm->subnet_up_event,
615 wait_us, interruptible));
621 * [in] Pointer to an osm_sm_t object.
624 * [in] Number of microseconds to wait.
627 * [in] Indicates whether the wait operation can be interrupted
628 * by external signals.
631 * CL_SUCCESS if the wait operation succeeded in response to the event
634 * CL_TIMEOUT if the specified time period elapses.
636 * CL_NOT_DONE if the wait was interrupted by an external signal.
638 * CL_ERROR if the wait operation failed.
645 /****f* OpenSM: State Manager/osm_sm_is_greater_than
647 * osm_sm_is_greater_than
650 * Compares two SM's (14.4.1.2)
654 static inline boolean_t
655 osm_sm_is_greater_than(IN const uint8_t l_priority,
656 IN const ib_net64_t l_guid,
657 IN const uint8_t r_priority, IN const ib_net64_t r_guid)
659 return (l_priority > r_priority
660 || (l_priority == r_priority
661 && cl_ntoh64(l_guid) < cl_ntoh64(r_guid)));
667 * [in] Priority of the SM on the "left"
670 * [in] GUID of the SM on the "left"
673 * [in] Priority of the SM on the "right"
676 * [in] GUID of the SM on the "right"
679 * Return TRUE if an sm with l_priority and l_guid is higher than an sm
680 * with r_priority and r_guid, return FALSE otherwise.
688 /****f* OpenSM: SM State Manager/osm_sm_state_mgr_process
690 * osm_sm_state_mgr_process
693 * Processes and maintains the states of the SM.
697 ib_api_status_t osm_sm_state_mgr_process(IN osm_sm_t *sm,
698 IN osm_sm_signal_t signal);
702 * [in] Pointer to an osm_sm_t object.
705 * [in] Signal to the state SM engine.
716 /****f* OpenSM: SM State Manager/osm_sm_state_mgr_signal_master_is_alive
718 * osm_sm_state_mgr_signal_master_is_alive
721 * Signals that the remote Master SM is alive.
722 * Need to clear the retry_number variable.
726 void osm_sm_state_mgr_signal_master_is_alive(IN osm_sm_t *sm);
730 * [in] Pointer to an osm_sm_t object.
741 /****f* OpenSM: SM State Manager/osm_sm_state_mgr_check_legality
743 * osm_sm_state_mgr_check_legality
746 * Checks the legality of the signal received, according to the
747 * current state of the SM state machine.
751 ib_api_status_t osm_sm_state_mgr_check_legality(IN osm_sm_t *sm,
752 IN osm_sm_signal_t signal);
756 * [in] Pointer to an osm_sm_t object.
759 * [in] Signal to the state SM engine.
770 void osm_report_sm_state(osm_sm_t *sm);
772 /****f* OpenSM: SM State Manager/osm_send_trap144
777 * Send trap 144 to the master SM.
781 int osm_send_trap144(osm_sm_t *sm, ib_net16_t local);
785 * [in] Pointer to an osm_sm_t object.
788 * [in] OtherLocalChanges mask in network byte order.
791 * 0 on success, non-zero value otherwise.
795 void osm_set_sm_priority(osm_sm_t *sm, uint8_t priority);
798 #endif /* _OSM_SM_H_ */