1
0
mirror of https://github.com/wfjm/w11.git synced 2026-02-05 16:25:25 +00:00

- the w11a rbus interface used so far a narrow dynamically adjusted

rbus->ibus window. Replaces with a 4k word window for whole IO page.
- utilize rlink protocol version 4 features in w11a backend
  - use attn notifies to dispatch attn handlers
  - use larger blocks (7*512 rather 1*512 bytes) for rdma transfers
  - use labo and merge csr updates with last block transfer
  - this combined reduces the number of round trips by a factor 2 to 3, 
    and in some cases the throughput accordingly.
This commit is contained in:
Walter F.J. Mueller
2015-01-04 19:18:35 +00:00
parent d87ac86f53
commit dde49d52e4
114 changed files with 3305 additions and 1244 deletions

View File

@@ -1,4 +1,4 @@
// $Id: RlinkServer.cpp 611 2014-12-10 23:23:58Z mueller $
// $Id: RlinkServer.cpp 628 2015-01-04 16:22:09Z mueller $
//
// Copyright 2013-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
@@ -13,6 +13,8 @@
//
// Revision History:
// Date Rev Version Comment
// 2014-12-30 625 2.1 adopt to Rlink V4 attn logic
// 2014-12-21 617 2.0.1 use kStat_M_RbTout for rbus timeout
// 2014-12-11 611 2.0 re-organize for rlink v4
// 2013-05-01 513 1.0.2 fTraceLevel now uint32_t
// 2013-04-21 509 1.0.1 add Resume(), reorganize server start handling
@@ -22,7 +24,7 @@
/*!
\file
\version $Id: RlinkServer.cpp 611 2014-12-10 23:23:58Z mueller $
\version $Id: RlinkServer.cpp 628 2015-01-04 16:22:09Z mueller $
\brief Implemenation of RlinkServer.
*/
@@ -65,7 +67,9 @@ RlinkServer::RlinkServer()
fStats()
{
fContext.SetStatus(0,
~(RlinkCommand::kStat_M_RbNak|RlinkCommand::kStat_M_RbErr));
~(RlinkCommand::kStat_M_RbTout |
RlinkCommand::kStat_M_RbNak |
RlinkCommand::kStat_M_RbErr));
fELoop.AddPollHandler(boost::bind(&RlinkServer::WakeupHandler, this, _1),
fWakeupEvent, POLLIN);
@@ -75,7 +79,9 @@ RlinkServer::RlinkServer()
fStats.Define(kStatNEloopPoll,"NEloopPoll","event loop turns (poll)");
fStats.Define(kStatNWakeupEvt,"NWakeupEvt","Wakeup events");
fStats.Define(kStatNRlinkEvt, "NRlinkEvt", "Rlink data events");
fStats.Define(kStatNAttnRead, "NAttnRead", "Attn read commands");
fStats.Define(kStatNAttnHdl ,"NAttnHdl" ,"Attn handler calls");
fStats.Define(kStatNAttnNoti ,"NAttnNoti" ,"Attn notifies processed");
fStats.Define(kStatNAttnHarv ,"NAttnHarv" ,"Attn handler restarts");
fStats.Define(kStatNAttn00, "NAttn00", "Attn bit 0 set");
fStats.Define(kStatNAttn01, "NAttn01", "Attn bit 1 set");
fStats.Define(kStatNAttn02, "NAttn02", "Attn bit 2 set");
@@ -147,6 +153,36 @@ void RlinkServer::AddAttnHandler(const attnhdl_t& attnhdl, uint16_t mask,
//------------------------------------------+-----------------------------------
//! FIXME_docs
void RlinkServer::GetAttnInfo(AttnArgs& args, RlinkCommandList& clist)
{
RlinkCommand& cmd0 = clist[0];
if (cmd0.Command() != RlinkCommand::kCmdAttn)
throw Rexception("RlinkServer::GetAttnInfo", "clist did't start with attn");
RerrMsg emsg;
if (!Exec(clist, emsg))
throw Rexception("RlinkServer::GetAttnInfo", "Exec() failed: ", emsg);
args.fAttnHarvest = cmd0.Data();
args.fHarvestDone = true;
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
void RlinkServer::GetAttnInfo(AttnArgs& args)
{
RlinkCommandList clist;
clist.AddAttn();
GetAttnInfo(args, clist);
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
void RlinkServer::RemoveAttnHandler(uint16_t mask, void* cdata)
{
boost::lock_guard<RlinkConnect> lock(*fspConn);
@@ -267,9 +303,9 @@ void RlinkServer::SignalAttnNotify(uint16_t apat)
// only called under lock !!
if (apat & fAttnNotiPatt) {
RlogMsg lmsg(LogFile(), 'W');
lmsg << "SignalAttnNotify: redundant notify: "
<< " have=" << RosPrintBvi(fAttnNotiPatt,16)
<< " apat=" << RosPrintBvi(apat,16);
lmsg << "SignalAttnNotify: redundant notify:"
<< " have=" << RosPrintBvi(fAttnNotiPatt,16)
<< " apat=" << RosPrintBvi(apat,16);
}
fAttnNotiPatt |= apat;
Wakeup();
@@ -398,58 +434,60 @@ void RlinkServer::StartOrResume(bool resume)
void RlinkServer::CallAttnHandler()
{
// FIXME_code: this is still V3 logic
// notifier pattern is ignored, only that one was received is used
fStats.Inc(kStatNAttnHdl);
// if notifier pending, transfer it to current attn pattern
if (fAttnNotiPatt) {
boost::lock_guard<RlinkConnect> lock(*fspConn);
uint16_t onoti = fAttnNotiPatt;
// Clear fAttnNotiPatt before clist is issued ! This avoids a race
// in case the attn read is followed immediately by a notify which
// is signaled during Exec().
fStats.Inc(kStatNAttnNoti);
fAttnPatt |= fAttnNotiPatt;
fAttnNotiPatt = 0;
RlinkCommandList clist;
clist.AddAttn();
fStats.Inc(kStatNAttnRead);
Exec(clist);
// FIXME_code: handle errors: bool ok =
uint16_t nattn = clist[0].Data();
fAttnPatt |= nattn;
if (onoti & (~nattn)) { // bits in notify not in attn ?
RlogMsg lmsg(LogFile(), 'W');
lmsg << "CallAttnHandler: missing lams in attn: "
<< " attn=" << RosPrintBvi(nattn,16)
<< " noti=" << RosPrintBvi(onoti,16);
}
for (size_t i=0; i<16; i++) {
if (nattn & (uint16_t(1)<<i)) fStats.Inc(kStatNAttn00+i);
}
}
// multiple handlers may be called for one attn bit
// do stats for pending attentions
for (size_t i=0; i<16; i++) {
if (fAttnPatt & (uint16_t(1)<<i)) fStats.Inc(kStatNAttn00+i);
}
// now call handlers, multiple handlers may be called for one attn bit
uint16_t hnext = 0;
uint16_t hdone = 0;
for (size_t i=0; i<fAttnDsc.size(); i++) {
uint16_t hmatch = fAttnPatt & fAttnDsc[i].fId.fMask;
if (hmatch) {
AttnArgs args(fAttnPatt, fAttnDsc[i].fId.fMask);
// FIXME_code: return code not used, yet
boost::lock_guard<RlinkConnect> lock(*fspConn);
// FIXME_code: return code not used, yet
fAttnDsc[i].fHandler(args);
if (!args.fHarvestDone)
Rexception("RlinkServer::CallAttnHandler()",
"Handler didn't set fHarvestDone");
uint16_t hnew = args.fAttnHarvest & ~fAttnDsc[i].fId.fMask;
hnext |= hnew;
hdone |= hmatch;
}
}
fAttnPatt &= ~hdone; // clear handled bits
if (fAttnPatt && fTraceLevel>0) {
RlogMsg lmsg(LogFile(), 'I');
lmsg << "eloop: unhandled attn, mask="
<< RosPrintBvi(fAttnPatt,16) << endl;
// if there are any unhandled attenions, do default handling which will
// ensure that attention harvest is done
if (fAttnPatt) {
AttnArgs args(fAttnPatt, fAttnPatt);
GetAttnInfo(args);
hnext |= args.fAttnHarvest & ~fAttnPatt;
if (fTraceLevel>0) {
RlogMsg lmsg(LogFile(), 'I');
lmsg << "eloop: unhandled attn, mask="
<< RosPrintBvi(fAttnPatt,16) << endl;
}
}
fAttnPatt = 0;
// finally replace current attn pattern by the attentions found during
// harvest and not yet handled
fAttnPatt = hnext;
if (fAttnPatt) fStats.Inc(kStatNAttnHarv);
return;
}