110923SN/A/* 210923SN/A * Copyright (c) 2015 ARM Limited 310923SN/A * All rights reserved 410923SN/A * 510923SN/A * The license below extends only to copyright in the software and shall 610923SN/A * not be construed as granting a license to any other intellectual 710923SN/A * property including but not limited to intellectual property relating 810923SN/A * to a hardware implementation of the functionality of the software 910923SN/A * licensed hereunder. You may use the software subject to the license 1010923SN/A * terms below provided that you ensure that this notice is replicated 1110923SN/A * unmodified and in its entirety in all distributions of the software, 1210923SN/A * modified or unmodified, in source code or in binary form. 1310923SN/A * 1410923SN/A * Redistribution and use in source and binary forms, with or without 1510923SN/A * modification, are permitted provided that the following conditions are 1610923SN/A * met: redistributions of source code must retain the above copyright 1710923SN/A * notice, this list of conditions and the following disclaimer; 1810923SN/A * redistributions in binary form must reproduce the above copyright 1910923SN/A * notice, this list of conditions and the following disclaimer in the 2010923SN/A * documentation and/or other materials provided with the distribution; 2110923SN/A * neither the name of the copyright holders nor the names of its 2210923SN/A * contributors may be used to endorse or promote products derived from 2310923SN/A * this software without specific prior written permission. 2410923SN/A * 2510923SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610923SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710923SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810923SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910923SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010923SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110923SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210923SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310923SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410923SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510923SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610923SN/A * 3710923SN/A * Authors: Gabor Dozsa 3810923SN/A */ 3910923SN/A 4010923SN/A/* @file 4111290Sgabor.dozsa@arm.com * Device module for a full duplex ethernet link for dist gem5 simulations. 4210923SN/A */ 4310923SN/A 4411290Sgabor.dozsa@arm.com#include "dev/net/dist_etherlink.hh" 4510923SN/A 4610923SN/A#include <arpa/inet.h> 4710923SN/A#include <sys/socket.h> 4810923SN/A#include <unistd.h> 4910923SN/A 5010923SN/A#include <cmath> 5110923SN/A#include <deque> 5210923SN/A#include <string> 5310923SN/A#include <vector> 5410923SN/A 5510923SN/A#include "base/random.hh" 5610923SN/A#include "base/trace.hh" 5711290Sgabor.dozsa@arm.com#include "debug/DistEthernet.hh" 5811290Sgabor.dozsa@arm.com#include "debug/DistEthernetPkt.hh" 5910923SN/A#include "debug/EthernetData.hh" 6011290Sgabor.dozsa@arm.com#include "dev/net/dist_iface.hh" 6111263SN/A#include "dev/net/etherdump.hh" 6211263SN/A#include "dev/net/etherint.hh" 6311263SN/A#include "dev/net/etherlink.hh" 6411263SN/A#include "dev/net/etherpkt.hh" 6511263SN/A#include "dev/net/tcp_iface.hh" 6610923SN/A#include "params/EtherLink.hh" 6710923SN/A#include "sim/core.hh" 6810923SN/A#include "sim/serialize.hh" 6910923SN/A#include "sim/system.hh" 7010923SN/A 7110923SN/Ausing namespace std; 7210923SN/A 7311290Sgabor.dozsa@arm.comDistEtherLink::DistEtherLink(const Params *p) 7413766Sgabeblack@google.com : SimObject(p), linkDelay(p->delay) 7510923SN/A{ 7611290Sgabor.dozsa@arm.com DPRINTF(DistEthernet,"DistEtherLink::DistEtherLink() " 7711290Sgabor.dozsa@arm.com "link delay:%llu ticksPerByte:%f\n", p->delay, p->speed); 7810923SN/A 7910923SN/A txLink = new TxLink(name() + ".link0", this, p->speed, p->delay_var, 8010923SN/A p->dump); 8110923SN/A rxLink = new RxLink(name() + ".link1", this, p->delay, p->dump); 8210923SN/A 8311290Sgabor.dozsa@arm.com Tick sync_repeat; 8411290Sgabor.dozsa@arm.com if (p->sync_repeat != 0) { 8511290Sgabor.dozsa@arm.com if (p->sync_repeat != p->delay) 8611290Sgabor.dozsa@arm.com warn("DistEtherLink(): sync_repeat is %lu and linkdelay is %lu", 8711290Sgabor.dozsa@arm.com p->sync_repeat, p->delay); 8811290Sgabor.dozsa@arm.com sync_repeat = p->sync_repeat; 8911290Sgabor.dozsa@arm.com } else { 9011290Sgabor.dozsa@arm.com sync_repeat = p->delay; 9111290Sgabor.dozsa@arm.com } 9210923SN/A 9311290Sgabor.dozsa@arm.com // create the dist (TCP) interface to talk to the peer gem5 processes. 9411290Sgabor.dozsa@arm.com distIface = new TCPIface(p->server_name, p->server_port, 9511290Sgabor.dozsa@arm.com p->dist_rank, p->dist_size, 9611703Smichael.lebeane@amd.com p->sync_start, sync_repeat, this, 9711703Smichael.lebeane@amd.com p->dist_sync_on_pseudo_op, p->is_switch, 9811290Sgabor.dozsa@arm.com p->num_nodes); 9911290Sgabor.dozsa@arm.com 10011290Sgabor.dozsa@arm.com localIface = new LocalIface(name() + ".int0", txLink, rxLink, distIface); 10110923SN/A} 10210923SN/A 10311290Sgabor.dozsa@arm.comDistEtherLink::~DistEtherLink() 10410923SN/A{ 10510923SN/A delete txLink; 10610923SN/A delete rxLink; 10710923SN/A delete localIface; 10811290Sgabor.dozsa@arm.com delete distIface; 10910923SN/A} 11010923SN/A 11113784Sgabeblack@google.comPort & 11213784Sgabeblack@google.comDistEtherLink::getPort(const std::string &if_name, PortID idx) 11310923SN/A{ 11413784Sgabeblack@google.com if (if_name == "int0") 11513784Sgabeblack@google.com return *localIface; 11613784Sgabeblack@google.com return SimObject::getPort(if_name, idx); 11710923SN/A} 11810923SN/A 11911290Sgabor.dozsa@arm.comvoid 12011290Sgabor.dozsa@arm.comDistEtherLink::serialize(CheckpointOut &cp) const 12110923SN/A{ 12211290Sgabor.dozsa@arm.com distIface->serializeSection(cp, "distIface"); 12311290Sgabor.dozsa@arm.com txLink->serializeSection(cp, "txLink"); 12411290Sgabor.dozsa@arm.com rxLink->serializeSection(cp, "rxLink"); 12510923SN/A} 12610923SN/A 12710923SN/Avoid 12811290Sgabor.dozsa@arm.comDistEtherLink::unserialize(CheckpointIn &cp) 12910923SN/A{ 13011290Sgabor.dozsa@arm.com distIface->unserializeSection(cp, "distIface"); 13111290Sgabor.dozsa@arm.com txLink->unserializeSection(cp, "txLink"); 13211290Sgabor.dozsa@arm.com rxLink->unserializeSection(cp, "rxLink"); 13310923SN/A} 13410923SN/A 13510923SN/Avoid 13611290Sgabor.dozsa@arm.comDistEtherLink::init() 13710923SN/A{ 13811290Sgabor.dozsa@arm.com DPRINTF(DistEthernet,"DistEtherLink::init() called\n"); 13911290Sgabor.dozsa@arm.com distIface->init(rxLink->doneEvent(), linkDelay); 14010923SN/A} 14110923SN/A 14210923SN/Avoid 14311290Sgabor.dozsa@arm.comDistEtherLink::startup() 14410923SN/A{ 14511290Sgabor.dozsa@arm.com DPRINTF(DistEthernet,"DistEtherLink::startup() called\n"); 14611290Sgabor.dozsa@arm.com distIface->startup(); 14710923SN/A} 14810923SN/A 14910923SN/Avoid 15011290Sgabor.dozsa@arm.comDistEtherLink::RxLink::setDistInt(DistIface *m) 15110923SN/A{ 15211290Sgabor.dozsa@arm.com assert(!distIface); 15311290Sgabor.dozsa@arm.com distIface = m; 15410923SN/A} 15510923SN/A 15610923SN/Avoid 15711290Sgabor.dozsa@arm.comDistEtherLink::RxLink::rxDone() 15810923SN/A{ 15910923SN/A assert(!busy()); 16010923SN/A 16110923SN/A // retrieve the packet that triggered the receive done event 16211290Sgabor.dozsa@arm.com packet = distIface->packetIn(); 16310923SN/A 16410923SN/A if (dump) 16510923SN/A dump->dump(packet); 16610923SN/A 16711290Sgabor.dozsa@arm.com DPRINTF(DistEthernetPkt, "DistEtherLink::DistLink::rxDone() " 16810923SN/A "packet received: len=%d\n", packet->length); 16910923SN/A DDUMP(EthernetData, packet->data, packet->length); 17010923SN/A 17110923SN/A localIface->sendPacket(packet); 17210923SN/A 17310923SN/A packet = nullptr; 17410923SN/A} 17510923SN/A 17610923SN/Avoid 17711290Sgabor.dozsa@arm.comDistEtherLink::TxLink::txDone() 17810923SN/A{ 17910923SN/A if (dump) 18010923SN/A dump->dump(packet); 18110923SN/A 18210923SN/A packet = nullptr; 18310923SN/A assert(!busy()); 18410923SN/A 18510923SN/A localIface->sendDone(); 18610923SN/A} 18710923SN/A 18810923SN/Abool 18911290Sgabor.dozsa@arm.comDistEtherLink::TxLink::transmit(EthPacketPtr pkt) 19010923SN/A{ 19110923SN/A if (busy()) { 19211290Sgabor.dozsa@arm.com DPRINTF(DistEthernet, "packet not sent, link busy\n"); 19310923SN/A return false; 19410923SN/A } 19510923SN/A 19610923SN/A packet = pkt; 19711701Smichael.lebeane@amd.com Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0); 19810923SN/A if (delayVar != 0) 19910923SN/A delay += random_mt.random<Tick>(0, delayVar); 20010923SN/A 20110923SN/A // send the packet to the peers 20211290Sgabor.dozsa@arm.com assert(distIface); 20311290Sgabor.dozsa@arm.com distIface->packetOut(pkt, delay); 20410923SN/A 20510923SN/A // schedule the send done event 20610923SN/A parent->schedule(doneEvent, curTick() + delay); 20710923SN/A 20810923SN/A return true; 20910923SN/A} 21010923SN/A 21110923SN/Avoid 21211290Sgabor.dozsa@arm.comDistEtherLink::Link::serialize(CheckpointOut &cp) const 21310923SN/A{ 21410923SN/A bool packet_exists = (packet != nullptr); 21511290Sgabor.dozsa@arm.com SERIALIZE_SCALAR(packet_exists); 21610923SN/A if (packet_exists) 21711290Sgabor.dozsa@arm.com packet->serialize("packet", cp); 21810923SN/A 21910923SN/A bool event_scheduled = event->scheduled(); 22011290Sgabor.dozsa@arm.com SERIALIZE_SCALAR(event_scheduled); 22110923SN/A if (event_scheduled) { 22210923SN/A Tick event_time = event->when(); 22311290Sgabor.dozsa@arm.com SERIALIZE_SCALAR(event_time); 22410923SN/A } 22510923SN/A} 22610923SN/A 22710923SN/Avoid 22811290Sgabor.dozsa@arm.comDistEtherLink::Link::unserialize(CheckpointIn &cp) 22910923SN/A{ 23010923SN/A bool packet_exists; 23111290Sgabor.dozsa@arm.com UNSERIALIZE_SCALAR(packet_exists); 23210923SN/A if (packet_exists) { 23311701Smichael.lebeane@amd.com packet = make_shared<EthPacketData>(); 23411290Sgabor.dozsa@arm.com packet->unserialize("packet", cp); 23510923SN/A } 23610923SN/A 23710923SN/A bool event_scheduled; 23811290Sgabor.dozsa@arm.com UNSERIALIZE_SCALAR(event_scheduled); 23910923SN/A if (event_scheduled) { 24010923SN/A Tick event_time; 24111290Sgabor.dozsa@arm.com UNSERIALIZE_SCALAR(event_time); 24210923SN/A parent->schedule(*event, event_time); 24310923SN/A } 24410923SN/A} 24510923SN/A 24611290Sgabor.dozsa@arm.comDistEtherLink::LocalIface::LocalIface(const std::string &name, 24710923SN/A TxLink *tx, 24810923SN/A RxLink *rx, 24911290Sgabor.dozsa@arm.com DistIface *m) : 25010923SN/A EtherInt(name), txLink(tx) 25110923SN/A{ 25210923SN/A tx->setLocalInt(this); 25310923SN/A rx->setLocalInt(this); 25411290Sgabor.dozsa@arm.com tx->setDistInt(m); 25511290Sgabor.dozsa@arm.com rx->setDistInt(m); 25610923SN/A} 25710923SN/A 25811290Sgabor.dozsa@arm.comDistEtherLink * 25911290Sgabor.dozsa@arm.comDistEtherLinkParams::create() 26010923SN/A{ 26111290Sgabor.dozsa@arm.com return new DistEtherLink(this); 26210923SN/A} 26310923SN/A 26410923SN/A 265