add a backoff algorithm when nacks are received by devices

add seperate response buffers and request queue sizes in bus bridge
add delay to respond to a nack in the bus bridge

src/dev/i8254xGBe.cc:
src/dev/ide_ctrl.cc:
src/dev/ns_gige.cc:
src/dev/pcidev.hh:
src/dev/sinic.cc:
    add backoff delay parameters
src/dev/io_device.cc:
src/dev/io_device.hh:
    add a backoff algorithm when nacks are received.
src/mem/bridge.cc:
src/mem/bridge.hh:
    add seperate response buffers and request queue sizes
    add a new parameters to specify how long before a nack in ready to go after a packet that needs to be nacked is received
src/mem/cache/cache_impl.hh:
    assert on the
src/mem/tport.cc:
    add a friendly assert to make sure the packet was inserted into the list

--HG--
extra : convert_revision : 3595ad932015a4ce2bb72772da7850ad91bd09b1
This commit is contained in:
Ali Saidi
2007-05-09 18:20:24 -04:00
parent 37b45e3c8c
commit 3c608bf765
11 changed files with 250 additions and 61 deletions

View File

@@ -1460,6 +1460,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IGbE)
SimObjectParam<System *> system;
SimObjectParam<Platform *> platform;
Param<Tick> min_backoff_delay;
Param<Tick> max_backoff_delay;
SimObjectParam<PciConfigData *> configdata;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
@@ -1481,6 +1483,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IGbE)
INIT_PARAM(system, "System pointer"),
INIT_PARAM(platform, "Platform pointer"),
INIT_PARAM(min_backoff_delay, "Minimum delay after receving a nack packed"),
INIT_PARAM(max_backoff_delay, "Maximum delay after receving a nack packed"),
INIT_PARAM(configdata, "PCI Config data"),
INIT_PARAM(pci_bus, "PCI bus ID"),
INIT_PARAM(pci_dev, "PCI device number"),
@@ -1505,6 +1509,8 @@ CREATE_SIM_OBJECT(IGbE)
params->name = getInstanceName();
params->platform = platform;
params->system = system;
params->min_backoff_delay = min_backoff_delay;
params->max_backoff_delay = max_backoff_delay;
params->configData = configdata;
params->busNum = pci_bus;
params->deviceNum = pci_dev;

View File

@@ -751,6 +751,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
SimObjectParam<System *> system;
SimObjectParam<Platform *> platform;
Param<Tick> min_backoff_delay;
Param<Tick> max_backoff_delay;
SimObjectParam<PciConfigData *> configdata;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
@@ -765,6 +767,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
INIT_PARAM(system, "System pointer"),
INIT_PARAM(platform, "Platform pointer"),
INIT_PARAM(min_backoff_delay, "Minimum delay after receving a nack packed"),
INIT_PARAM(max_backoff_delay, "Maximum delay after receving a nack packed"),
INIT_PARAM(configdata, "PCI Config data"),
INIT_PARAM(pci_bus, "PCI bus ID"),
INIT_PARAM(pci_dev, "PCI device number"),
@@ -781,6 +785,8 @@ CREATE_SIM_OBJECT(IdeController)
params->name = getInstanceName();
params->platform = platform;
params->system = system;
params->min_backoff_delay = min_backoff_delay;
params->max_backoff_delay = max_backoff_delay;
params->configData = configdata;
params->busNum = pci_bus;
params->deviceNum = pci_dev;

View File

@@ -93,7 +93,8 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list)
DmaPort::DmaPort(DmaDevice *dev, System *s)
: Port(dev->name() + "-dmaport", dev), device(dev), sys(s),
pendingCount(0), actionInProgress(0), drainEvent(NULL)
pendingCount(0), actionInProgress(0), drainEvent(NULL),
backoffTime(0), inRetry(false), backoffEvent(this)
{ }
bool
@@ -104,12 +105,27 @@ DmaPort::recvTiming(PacketPtr pkt)
if (pkt->result == Packet::Nacked) {
DPRINTF(DMA, "Received nacked Pkt %#x with State: %#x Addr: %#x\n",
pkt, pkt->senderState, pkt->getAddr());
if (backoffTime < device->minBackoffDelay)
backoffTime = device->minBackoffDelay;
else if (backoffTime < device->maxBackoffDelay)
backoffTime <<= 1;
if (backoffEvent.scheduled())
backoffEvent.reschedule(curTick + backoffTime);
else
backoffEvent.schedule(curTick + backoffTime);
DPRINTF(DMA, "Backoff time set to %d ticks\n", backoffTime);
pkt->reinitNacked();
sendDma(pkt, true);
queueDma(pkt, true);
} else if (pkt->senderState) {
DmaReqState *state;
DPRINTF(DMA, "Received response Pkt %#x with State: %#x Addr: %#x\n",
pkt, pkt->senderState, pkt->getAddr());
backoffTime >>= 2;
DPRINTF(DMA, "Received response Pkt %#x with State: %#x Addr: %#x size: %#x\n",
pkt, pkt->senderState, pkt->getAddr(), pkt->req->getSize());
state = dynamic_cast<DmaReqState*>(pkt->senderState);
pendingCount--;
@@ -117,6 +133,7 @@ DmaPort::recvTiming(PacketPtr pkt)
assert(state);
state->numBytes += pkt->req->getSize();
assert(state->totBytes >= state->numBytes);
if (state->totBytes == state->numBytes) {
state->completionEvent->process();
delete state;
@@ -136,7 +153,8 @@ DmaPort::recvTiming(PacketPtr pkt)
}
DmaDevice::DmaDevice(Params *p)
: PioDevice(p), dmaPort(NULL)
: PioDevice(p), dmaPort(NULL), minBackoffDelay(p->min_backoff_delay),
maxBackoffDelay(p->max_backoff_delay)
{ }
@@ -165,19 +183,31 @@ DmaPort::drain(Event *de)
void
DmaPort::recvRetry()
{
assert(transmitList.size());
PacketPtr pkt = transmitList.front();
bool result = true;
while (result && transmitList.size()) {
do {
DPRINTF(DMA, "Retry on Packet %#x with senderState: %#x\n",
pkt, pkt->senderState);
result = sendTiming(pkt);
if (result) {
DPRINTF(DMA, "-- Done\n");
transmitList.pop_front();
inRetry = false;
} else {
inRetry = true;
DPRINTF(DMA, "-- Failed, queued\n");
}
} while (!backoffTime && result && transmitList.size());
if (transmitList.size() && backoffTime && !inRetry) {
DPRINTF(DMA, "Scheduling backoff for %d\n", curTick+backoffTime);
if (!backoffEvent.scheduled())
backoffEvent.schedule(backoffTime+curTick);
}
DPRINTF(DMA, "TransmitList: %d, backoffTime: %d inRetry: %d es: %d\n",
transmitList.size(), backoffTime, inRetry,
backoffEvent.scheduled());
}
@@ -204,33 +234,61 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
assert(pendingCount >= 0);
pendingCount++;
sendDma(pkt);
queueDma(pkt);
}
}
void
DmaPort::queueDma(PacketPtr pkt, bool front)
{
if (front)
transmitList.push_front(pkt);
else
transmitList.push_back(pkt);
sendDma();
}
void
DmaPort::sendDma(PacketPtr pkt, bool front)
DmaPort::sendDma()
{
// some kind of selction between access methods
// more work is going to have to be done to make
// switching actually work
assert(transmitList.size());
PacketPtr pkt = transmitList.front();
System::MemoryMode state = sys->getMemoryMode();
if (state == System::Timing) {
if (backoffEvent.scheduled() || inRetry) {
DPRINTF(DMA, "Can't send immediately, waiting for retry or backoff timer\n");
return;
}
DPRINTF(DMA, "Attempting to send Packet %#x with addr: %#x\n",
pkt, pkt->getAddr());
if (transmitList.size() || !sendTiming(pkt)) {
if (front)
transmitList.push_front(pkt);
else
transmitList.push_back(pkt);
DPRINTF(DMA, "-- Failed: queued\n");
} else {
DPRINTF(DMA, "-- Done\n");
bool result;
do {
result = sendTiming(pkt);
if (result) {
transmitList.pop_front();
DPRINTF(DMA, "-- Done\n");
} else {
inRetry = true;
DPRINTF(DMA, "-- Failed: queued\n");
}
} while (result && !backoffTime && transmitList.size());
if (transmitList.size() && backoffTime && !inRetry &&
!backoffEvent.scheduled()) {
backoffEvent.schedule(backoffTime+curTick);
}
} else if (state == System::Atomic) {
transmitList.pop_front();
Tick lat;
lat = sendAtomic(pkt);
assert(pkt->senderState);

View File

@@ -107,6 +107,14 @@ class DmaPort : public Port
* here.*/
Event *drainEvent;
/** time to wait between sending another packet, increases as NACKs are
* recived, decreases as responses are recived. */
Tick backoffTime;
/** If the port is currently waiting for a retry before it can send whatever
* it is that it's sending. */
bool inRetry;
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt)
{ panic("dma port shouldn't be used for pio access."); M5_DUMMY_RETURN }
@@ -122,7 +130,11 @@ class DmaPort : public Port
AddrRangeList &snoop)
{ resp.clear(); snoop.clear(); }
void sendDma(PacketPtr pkt, bool front = false);
void queueDma(PacketPtr pkt, bool front = false);
void sendDma();
/** event to give us a kick every time we backoff time is reached. */
EventWrapper<DmaPort, &DmaPort::sendDma> backoffEvent;
public:
DmaPort(DmaDevice *dev, System *s);
@@ -249,8 +261,17 @@ class BasicPioDevice : public PioDevice
class DmaDevice : public PioDevice
{
protected:
public:
struct Params : public PioDevice::Params
{
Tick min_backoff_delay;
Tick max_backoff_delay;
};
protected:
DmaPort *dmaPort;
Tick minBackoffDelay;
Tick maxBackoffDelay;
public:
DmaDevice(Params *p);

View File

@@ -2812,6 +2812,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
SimObjectParam<System *> system;
SimObjectParam<Platform *> platform;
Param<Tick> min_backoff_delay;
Param<Tick> max_backoff_delay;
SimObjectParam<PciConfigData *> configdata;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
@@ -2846,6 +2848,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
INIT_PARAM(system, "System pointer"),
INIT_PARAM(platform, "Platform pointer"),
INIT_PARAM(min_backoff_delay, "Minimum delay after receving a nack packed"),
INIT_PARAM(max_backoff_delay, "Maximum delay after receving a nack packed"),
INIT_PARAM(configdata, "PCI Config data"),
INIT_PARAM(pci_bus, "PCI bus ID"),
INIT_PARAM(pci_dev, "PCI device number"),
@@ -2884,6 +2888,8 @@ CREATE_SIM_OBJECT(NSGigE)
params->name = getInstanceName();
params->platform = platform;
params->system = system;
params->min_backoff_delay = min_backoff_delay;
params->max_backoff_delay = max_backoff_delay;
params->configData = configdata;
params->busNum = pci_bus;
params->deviceNum = pci_dev;

View File

@@ -105,7 +105,7 @@ class PciDev : public DmaDevice
};
public:
struct Params : public PioDevice::Params
struct Params : public DmaDevice::Params
{
/**
* A pointer to the object that contains the first 64 bytes of

View File

@@ -1635,6 +1635,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS_WNS(Sinic, SinicDevice)
SimObjectParam<System *> system;
SimObjectParam<Platform *> platform;
Param<Tick> min_backoff_delay;
Param<Tick> max_backoff_delay;
SimObjectParam<PciConfigData *> configdata;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
@@ -1678,6 +1680,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS_WNS(Sinic, SinicDevice)
INIT_PARAM(system, "System pointer"),
INIT_PARAM(platform, "Platform pointer"),
INIT_PARAM(min_backoff_delay, "Minimum delay after receving a nack packed"),
INIT_PARAM(max_backoff_delay, "Maximum delay after receving a nack packed"),
INIT_PARAM(configdata, "PCI Config data"),
INIT_PARAM(pci_bus, "PCI bus ID"),
INIT_PARAM(pci_dev, "PCI device number"),
@@ -1723,6 +1727,8 @@ CREATE_SIM_OBJECT_WNS(Sinic, SinicDevice)
params->name = getInstanceName();
params->platform = platform;
params->system = system;
params->min_backoff_delay = min_backoff_delay;
params->max_backoff_delay = max_backoff_delay;
params->configData = configdata;
params->busNum = pci_bus;
params->deviceNum = pci_dev;