[ofa-general] [PATCH] ibutils: mkey handling basic modeling

Yevgeny Kliteynik kliteyn at dev.mellanox.co.il
Tue Oct 7 02:31:38 PDT 2008


[On behalf of Vladimir Zdornov]

A basic implementation of mkey mechanism.
All nodes share a common timer which decrements
the counters on the registered nodes every 1 sec.

Signed-off-by:  Vladimir Zdornov <zdv at mellanox.co.il>

---
 ibmgtsim/src/sma.cpp |  151 ++++++++++++++++++++++++++++++++++++++++++++++++++
 ibmgtsim/src/sma.h   |   53 +++++++++++++++++
 2 files changed, 204 insertions(+), 0 deletions(-)

diff --git a/ibmgtsim/src/sma.cpp b/ibmgtsim/src/sma.cpp
index 446ec56..ea82d77 100644
--- a/ibmgtsim/src/sma.cpp
+++ b/ibmgtsim/src/sma.cpp
@@ -45,6 +45,11 @@
  *
  *********/

+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <string>
+
 #include "msgmgr.h"
 #include "simmsg.h"
 #include "sim.h"
@@ -89,6 +94,85 @@ ibms_dump_mad(
   }
 }

+// CLASS SMATimer
+
+SMATimer::SMATimer(int t):time(t)
+{
+  pthread_mutex_init(&timerMutex, NULL);
+  tid = pthread_create(&th, NULL, SMATimer::timerRun, this);
+  if (tid) {
+    MSGREG(err0, 'E', "Couldn't create timer thread $ !", "processMad");
+    MSGSND(err0, tid);
+    }
+  MSGREG(inf1, 'V', "SMA timer on!", "processMad");
+  MSGSND(inf1);
+}
+
+void SMATimer::terminate()
+{
+  pthread_cancel(th);
+}
+
+void* SMATimer::timerRun(void* p)
+{
+  SMATimer* p_timer = (SMATimer*) p;
+  while(1) {
+    MSGREG(inf1, 'V', "Sleeping for $ secs !", "processMad");
+    MSGSND(inf1,p_timer->time);
+
+    sleep(p_timer->time);
+    pthread_mutex_lock(&p_timer->timerMutex);
+    unsigned i=0;
+    while (i<p_timer->L.size()) {
+      int res = p_timer->L[i].f(p_timer->L[i].data);
+      if (!res)
+	p_timer->L.erase(p_timer->L.begin()+i);
+      else
+	i++;
+    }
+    pthread_mutex_unlock(&p_timer->timerMutex);
+  }
+}
+
+void SMATimer::reg (reg_t r)
+{
+  pthread_mutex_lock(&timerMutex);
+  L.push_back(r);
+  pthread_mutex_unlock(&timerMutex);
+}
+
+void SMATimer::unreg (void* data)
+{
+  pthread_mutex_lock(&timerMutex);
+  for (unsigned i=0;i<L.size();i++)
+    if (L[i].data == data) {
+      L.erase(L.begin()+i);
+      return;
+    }
+  pthread_mutex_unlock(&timerMutex);
+}
+
+// CLASS IBMSSma
+
+SMATimer IBMSSma::mkeyTimer = SMATimer(T_FREQ);
+
+int IBMSSma::cbMkey(void* data)
+{
+  portTiming* pT = (portTiming*) data;
+  pthread_mutex_lock(&pT->mut);
+  pT->counter--;
+  if (pT->counter > 0) {
+    pthread_mutex_unlock(&pT->mut);
+    return 1;
+  }
+  // Need to zero m_key
+  pT->pInfo->m_key = 0;
+  pT->timerOn = 0;
+  pthread_mutex_unlock(&pT->mut);
+
+  return 0;
+}
+
 void IBMSSma::initSwitchInfo()
 {
   IBNode              *pNodeData;
@@ -392,6 +476,14 @@ IBMSSma::IBMSSma(IBMSNode *pSNode, list_uint16 mgtClasses) :
   initPortInfo();
   //Init VL Arbitration ports vector size and table
   pSimNode->vlArbPortEntry.resize(pSimNode->nodeInfo.num_ports + 1);
+  //Init ports' timing vector
+  vPT.resize(pSimNode->nodeInfo.num_ports + 1);
+  for (unsigned i=0;i<vPT.size();i++)
+    if ((pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH) || i!=0) {
+      vPT[i].pInfo = &(pSimNode->nodePortsInfo[i]);
+      pthread_mutex_init(&vPT[i].mut, NULL);
+      vPT[i].timerOn = 0;
+    }
   initVlArbitTable();

   initPKeyTables();
@@ -1482,6 +1574,7 @@ int IBMSSma::madValidation(ibms_mad_msg_t &madMsg)

 int IBMSSma::processMad(uint8_t inPort, ibms_mad_msg_t &madMsg)
 {
+
   MSG_ENTER_FUNC;

   ibms_mad_msg_t      respMadMsg;
@@ -1519,6 +1612,64 @@ int IBMSSma::processMad(uint8_t inPort, ibms_mad_msg_t &madMsg)
     memcpy(pRespSmp, pReqSmp, sizeof(ib_smp_t));
   }

+  // perform m_key check
+  unsigned mPort = inPort;
+  if (pSimNode->nodeInfo.node_type == IB_NODE_TYPE_SWITCH)
+    mPort = 0;
+
+  ib_net64_t m_key1 = ((ib_smp_t*)(&madMsg.header))->m_key;
+
+  pthread_mutex_lock(&vPT[mPort].mut);
+  ib_net64_t m_key2 = vPT[mPort].pInfo->m_key;
+
+  MSGREG(inf21, 'I', "Mkeys current: $, received: $!", "processMad");
+  MSGSND(inf21, cl_ntoh64(m_key2), cl_ntoh64(m_key1));
+
+  if (m_key2 && (m_key1 != m_key2) && madMsg.header.method == IB_MAD_METHOD_SET) {
+    MSGREG(inf22, 'I', "Mkeys mismatch!", "processMad");
+    MSGSND(inf22);
+
+    // Timer already running
+    if (vPT[mPort].timerOn) {
+      MSGREG(inf2, 'I', "Timer already on, counter: $!", "processMad");
+      MSGSND(inf2,vPT[mPort].counter);
+
+      MSG_EXIT_FUNC;
+      pthread_mutex_unlock(&vPT[mPort].mut);
+      return 0;
+    }
+    // Start the timer
+    else {
+      vPT[mPort].counter = cl_ntoh16(vPT[mPort].pInfo->m_key_lease_period);
+      vPT[mPort].timerOn = 1;
+      reg_t tmp;
+      tmp.f = cbMkey;
+      tmp.data = &vPT[mPort];
+
+      MSGREG(inf2, 'I', "Starting timer with counter $!", "processMad");
+      MSGSND(inf2,vPT[mPort].counter);
+
+      pthread_mutex_unlock(&vPT[mPort].mut);
+      mkeyTimer.reg(tmp);
+
+
+      MSG_EXIT_FUNC;
+
+      return 0;
+    }
+  }
+
+  if ((m_key1 == m_key2) && (vPT[mPort].timerOn)) {
+    MSGREG(inf2, 'I', "Stopping timer!", "processMad");
+    MSGSND(inf2);
+
+    vPT[mPort].timerOn = 0;
+    pthread_mutex_unlock(&vPT[mPort].mut);
+    mkeyTimer.unreg(&vPT[mPort]);
+  }
+
+  pthread_mutex_unlock(&vPT[mPort].mut);
+
   switch (attributeId) {
   case IB_MAD_ATTR_NODE_DESC:
     MSGREG(inf5, 'I', "Attribute being handled is $ !", "processMad");
diff --git a/ibmgtsim/src/sma.h b/ibmgtsim/src/sma.h
index 4241ca0..c222175 100644
--- a/ibmgtsim/src/sma.h
+++ b/ibmgtsim/src/sma.h
@@ -47,6 +47,9 @@
 #ifndef SMA_H
 #define SMA_H

+#include <pthread.h>
+#include <vector>
+#include <unistd.h>
 #include <ibdm/Fabric.h>
 #include "simmsg.h"
 #include "server.h"
@@ -83,8 +86,58 @@ ibms_dump_mad( const ibms_mad_msg_t &madMsg, const uint8_t dir);
 *
 *********/

+// Returns 0 if entry should be removed and 1 otherwise
+typedef int (*cbFunc)(void*);
+
+typedef struct reg_
+{
+  cbFunc f;
+  void* data;
+} reg_t;
+
+class SMATimer
+{
+  // Mutex of the timer
+  pthread_mutex_t timerMutex;
+  // Timer thread function
+  static void* timerRun(void* p);
+  // Thread id
+  int tid;
+  // Thread
+  pthread_t th;
+  // Registered objects list
+  vector<reg_t> L;
+  // Sleep time
+  int time;
+
+ public:
+  SMATimer(int time);
+  void terminate();
+  // Timer registration function
+  void reg(reg_t r);
+  // Removes registered object identified by POINTER
+  void unreg(void* data);
+};
+
+#define T_FREQ 1
+
+typedef struct portTiming_
+{
+  ib_port_info_t* pInfo;
+  unsigned counter;
+  int timerOn;
+  pthread_mutex_t mut;
+} portTiming;
+
 class IBMSSma : IBMSMadProcessor {

+  // m_key callback function
+  static int cbMkey(void* data);
+  // M_key timer
+  static SMATimer mkeyTimer;
+
+  vector<portTiming> vPT;
+
   /* init functions of node structures */
   void initSwitchInfo();
   void initNodeInfo();
-- 
1.5.1.4




More information about the general mailing list