dist_etherlink.cc revision 11703
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/etherobject.hh" 6511263SN/A#include "dev/net/etherpkt.hh" 6611263SN/A#include "dev/net/tcp_iface.hh" 6710923SN/A#include "params/EtherLink.hh" 6810923SN/A#include "sim/core.hh" 6910923SN/A#include "sim/serialize.hh" 7010923SN/A#include "sim/system.hh" 7110923SN/A 7210923SN/Ausing namespace std; 7310923SN/A 7411290Sgabor.dozsa@arm.comDistEtherLink::DistEtherLink(const Params *p) 7511290Sgabor.dozsa@arm.com : EtherObject(p), linkDelay(p->delay) 7610923SN/A{ 7711290Sgabor.dozsa@arm.com DPRINTF(DistEthernet,"DistEtherLink::DistEtherLink() " 7811290Sgabor.dozsa@arm.com "link delay:%llu ticksPerByte:%f\n", p->delay, p->speed); 7910923SN/A 8010923SN/A txLink = new TxLink(name() + ".link0", this, p->speed, p->delay_var, 8110923SN/A p->dump); 8210923SN/A rxLink = new RxLink(name() + ".link1", this, p->delay, p->dump); 8310923SN/A 8411290Sgabor.dozsa@arm.com Tick sync_repeat; 8511290Sgabor.dozsa@arm.com if (p->sync_repeat != 0) { 8611290Sgabor.dozsa@arm.com if (p->sync_repeat != p->delay) 8711290Sgabor.dozsa@arm.com warn("DistEtherLink(): sync_repeat is %lu and linkdelay is %lu", 8811290Sgabor.dozsa@arm.com p->sync_repeat, p->delay); 8911290Sgabor.dozsa@arm.com sync_repeat = p->sync_repeat; 9011290Sgabor.dozsa@arm.com } else { 9111290Sgabor.dozsa@arm.com sync_repeat = p->delay; 9211290Sgabor.dozsa@arm.com } 9310923SN/A 9411290Sgabor.dozsa@arm.com // create the dist (TCP) interface to talk to the peer gem5 processes. 9511290Sgabor.dozsa@arm.com distIface = new TCPIface(p->server_name, p->server_port, 9611290Sgabor.dozsa@arm.com p->dist_rank, p->dist_size, 9711703Smichael.lebeane@amd.com p->sync_start, sync_repeat, this, 9811703Smichael.lebeane@amd.com p->dist_sync_on_pseudo_op, p->is_switch, 9911290Sgabor.dozsa@arm.com p->num_nodes); 10011290Sgabor.dozsa@arm.com 10111290Sgabor.dozsa@arm.com localIface = new LocalIface(name() + ".int0", txLink, rxLink, distIface); 10210923SN/A} 10310923SN/A 10411290Sgabor.dozsa@arm.comDistEtherLink::~DistEtherLink() 10510923SN/A{ 10610923SN/A delete txLink; 10710923SN/A delete rxLink; 10810923SN/A delete localIface; 10911290Sgabor.dozsa@arm.com delete distIface; 11010923SN/A} 11110923SN/A 11210923SN/AEtherInt* 11311290Sgabor.dozsa@arm.comDistEtherLink::getEthPort(const std::string &if_name, int idx) 11410923SN/A{ 11510923SN/A if (if_name != "int0") { 11610923SN/A return nullptr; 11710923SN/A } else { 11810923SN/A panic_if(localIface->getPeer(), "interface already connected to"); 11910923SN/A } 12010923SN/A return localIface; 12110923SN/A} 12210923SN/A 12311290Sgabor.dozsa@arm.comvoid 12411290Sgabor.dozsa@arm.comDistEtherLink::serialize(CheckpointOut &cp) const 12510923SN/A{ 12611290Sgabor.dozsa@arm.com distIface->serializeSection(cp, "distIface"); 12711290Sgabor.dozsa@arm.com txLink->serializeSection(cp, "txLink"); 12811290Sgabor.dozsa@arm.com rxLink->serializeSection(cp, "rxLink"); 12910923SN/A} 13010923SN/A 13110923SN/Avoid 13211290Sgabor.dozsa@arm.comDistEtherLink::unserialize(CheckpointIn &cp) 13310923SN/A{ 13411290Sgabor.dozsa@arm.com distIface->unserializeSection(cp, "distIface"); 13511290Sgabor.dozsa@arm.com txLink->unserializeSection(cp, "txLink"); 13611290Sgabor.dozsa@arm.com rxLink->unserializeSection(cp, "rxLink"); 13710923SN/A} 13810923SN/A 13910923SN/Avoid 14011290Sgabor.dozsa@arm.comDistEtherLink::init() 14110923SN/A{ 14211290Sgabor.dozsa@arm.com DPRINTF(DistEthernet,"DistEtherLink::init() called\n"); 14311290Sgabor.dozsa@arm.com distIface->init(rxLink->doneEvent(), linkDelay); 14410923SN/A} 14510923SN/A 14610923SN/Avoid 14711290Sgabor.dozsa@arm.comDistEtherLink::startup() 14810923SN/A{ 14911290Sgabor.dozsa@arm.com DPRINTF(DistEthernet,"DistEtherLink::startup() called\n"); 15011290Sgabor.dozsa@arm.com distIface->startup(); 15110923SN/A} 15210923SN/A 15310923SN/Avoid 15411290Sgabor.dozsa@arm.comDistEtherLink::RxLink::setDistInt(DistIface *m) 15510923SN/A{ 15611290Sgabor.dozsa@arm.com assert(!distIface); 15711290Sgabor.dozsa@arm.com distIface = m; 15810923SN/A} 15910923SN/A 16010923SN/Avoid 16111290Sgabor.dozsa@arm.comDistEtherLink::RxLink::rxDone() 16210923SN/A{ 16310923SN/A assert(!busy()); 16410923SN/A 16510923SN/A // retrieve the packet that triggered the receive done event 16611290Sgabor.dozsa@arm.com packet = distIface->packetIn(); 16710923SN/A 16810923SN/A if (dump) 16910923SN/A dump->dump(packet); 17010923SN/A 17111290Sgabor.dozsa@arm.com DPRINTF(DistEthernetPkt, "DistEtherLink::DistLink::rxDone() " 17210923SN/A "packet received: len=%d\n", packet->length); 17310923SN/A DDUMP(EthernetData, packet->data, packet->length); 17410923SN/A 17510923SN/A localIface->sendPacket(packet); 17610923SN/A 17710923SN/A packet = nullptr; 17810923SN/A} 17910923SN/A 18010923SN/Avoid 18111290Sgabor.dozsa@arm.comDistEtherLink::TxLink::txDone() 18210923SN/A{ 18310923SN/A if (dump) 18410923SN/A dump->dump(packet); 18510923SN/A 18610923SN/A packet = nullptr; 18710923SN/A assert(!busy()); 18810923SN/A 18910923SN/A localIface->sendDone(); 19010923SN/A} 19110923SN/A 19210923SN/Abool 19311290Sgabor.dozsa@arm.comDistEtherLink::TxLink::transmit(EthPacketPtr pkt) 19410923SN/A{ 19510923SN/A if (busy()) { 19611290Sgabor.dozsa@arm.com DPRINTF(DistEthernet, "packet not sent, link busy\n"); 19710923SN/A return false; 19810923SN/A } 19910923SN/A 20010923SN/A packet = pkt; 20111701Smichael.lebeane@amd.com Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0); 20210923SN/A if (delayVar != 0) 20310923SN/A delay += random_mt.random<Tick>(0, delayVar); 20410923SN/A 20510923SN/A // send the packet to the peers 20611290Sgabor.dozsa@arm.com assert(distIface); 20711290Sgabor.dozsa@arm.com distIface->packetOut(pkt, delay); 20810923SN/A 20910923SN/A // schedule the send done event 21010923SN/A parent->schedule(doneEvent, curTick() + delay); 21110923SN/A 21210923SN/A return true; 21310923SN/A} 21410923SN/A 21510923SN/Avoid 21611290Sgabor.dozsa@arm.comDistEtherLink::Link::serialize(CheckpointOut &cp) const 21710923SN/A{ 21810923SN/A bool packet_exists = (packet != nullptr); 21911290Sgabor.dozsa@arm.com SERIALIZE_SCALAR(packet_exists); 22010923SN/A if (packet_exists) 22111290Sgabor.dozsa@arm.com packet->serialize("packet", cp); 22210923SN/A 22310923SN/A bool event_scheduled = event->scheduled(); 22411290Sgabor.dozsa@arm.com SERIALIZE_SCALAR(event_scheduled); 22510923SN/A if (event_scheduled) { 22610923SN/A Tick event_time = event->when(); 22711290Sgabor.dozsa@arm.com SERIALIZE_SCALAR(event_time); 22810923SN/A } 22910923SN/A} 23010923SN/A 23110923SN/Avoid 23211290Sgabor.dozsa@arm.comDistEtherLink::Link::unserialize(CheckpointIn &cp) 23310923SN/A{ 23410923SN/A bool packet_exists; 23511290Sgabor.dozsa@arm.com UNSERIALIZE_SCALAR(packet_exists); 23610923SN/A if (packet_exists) { 23711701Smichael.lebeane@amd.com packet = make_shared<EthPacketData>(); 23811290Sgabor.dozsa@arm.com packet->unserialize("packet", cp); 23910923SN/A } 24010923SN/A 24110923SN/A bool event_scheduled; 24211290Sgabor.dozsa@arm.com UNSERIALIZE_SCALAR(event_scheduled); 24310923SN/A if (event_scheduled) { 24410923SN/A Tick event_time; 24511290Sgabor.dozsa@arm.com UNSERIALIZE_SCALAR(event_time); 24610923SN/A parent->schedule(*event, event_time); 24710923SN/A } 24810923SN/A} 24910923SN/A 25011290Sgabor.dozsa@arm.comDistEtherLink::LocalIface::LocalIface(const std::string &name, 25110923SN/A TxLink *tx, 25210923SN/A RxLink *rx, 25311290Sgabor.dozsa@arm.com DistIface *m) : 25410923SN/A EtherInt(name), txLink(tx) 25510923SN/A{ 25610923SN/A tx->setLocalInt(this); 25710923SN/A rx->setLocalInt(this); 25811290Sgabor.dozsa@arm.com tx->setDistInt(m); 25911290Sgabor.dozsa@arm.com rx->setDistInt(m); 26010923SN/A} 26110923SN/A 26211290Sgabor.dozsa@arm.comDistEtherLink * 26311290Sgabor.dozsa@arm.comDistEtherLinkParams::create() 26410923SN/A{ 26511290Sgabor.dozsa@arm.com return new DistEtherLink(this); 26610923SN/A} 26710923SN/A 26810923SN/A 269