Skip to content

Commit

Permalink
incomplete work on qos
Browse files Browse the repository at this point in the history
  • Loading branch information
cjdelisle committed Oct 2, 2014
1 parent 5388b97 commit c9fe170
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 83 deletions.
3 changes: 1 addition & 2 deletions interface/test/InterfaceController_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ static int reconnectionNewEndpointTest(struct InterfaceController* ifController,

Message_shift(outgoing, SwitchHeader_SIZE, NULL);
Bits_memcpyConst(outgoing->bytes, (&(struct SwitchHeader) {
.label_be = Endian_hostToBigEndian64(1),
.lowBits_be = 0
.label_be = Endian_hostToBigEndian64(1)
}), SwitchHeader_SIZE);

wrapped->sendMessage(outgoing, wrapped);
Expand Down
11 changes: 3 additions & 8 deletions net/Ducttape.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,13 +939,9 @@ static uint8_t handleControlMessage(struct Ducttape_pvt* context,
// Determine whether the "cause" packet is a control message.
bool isCtrlCause = false;
#ifdef Version_7_COMPAT
if (SwitchHeader_TYPE_CONTROL ==
SwitchHeader_getMessageType(&ctrl->content.error.cause))
{
if (SwitchHeader_isV7Ctrl(&ctrl->content.error.cause)) {
isCtrlCause = true;
} else if (SwitchHeader_TYPE_DATA <
SwitchHeader_getMessageType(&ctrl->content.error.cause))
{
} else {
#endif
if (ctrl->content.error.causeHandle == 0xffffffff) {
isCtrlCause = true;
Expand Down Expand Up @@ -1110,8 +1106,7 @@ static uint8_t incomingFromSwitch(struct Message* message, struct Interface* swi
switchHeader->label_be = Bits_bitReverse64(switchHeader->label_be);

#ifdef Version_7_COMPAT
// The v7 method of signaling that a packet is a ctrl packet...
if (SwitchHeader_getSuppressErrors(switchHeader) && !SwitchHeader_getCongestion(switchHeader)) {
if (SwitchHeader_isV7Ctrl(switchHeader)) {
return handleControlMessage(context, message, switchHeader, switchIf, false);
}
#endif
Expand Down
8 changes: 3 additions & 5 deletions net/SwitchPinger.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static uint8_t receiveMessage(struct Message* msg, struct Interface* iface)
if (handle != 0xffffffff) {
Message_push32(msg, handle, NULL);
handle = 0xffffffff;
Assert_true(SwitchHeader_getMessageType(switchHeader) == SwitchHeader_TYPE_CONTROL);
Assert_true(SwitchHeader_isV7Ctrl(switchHeader));
}
#endif
Assert_true(handle == 0xffffffff);
Expand Down Expand Up @@ -251,15 +251,13 @@ static void sendPing(String* data, void* sendPingContext)
switchHeader->label_be = Endian_hostToBigEndian64(p->label);

SwitchHeader_setVersion(switchHeader, SwitchHeader_CURRENT_VERSION);
SwitchHeader_setPackedPenalty(switchHeader, 0);
SwitchHeader_setPenalty(switchHeader, 0);
SwitchHeader_setCongestion(switchHeader, 0);

#ifdef Version_7_COMPAT
// v7 detects ctrl packets by the bit which has been
// re-appropriated for suppression of errors.
SwitchHeader_setSuppressErrors(switchHeader, 1);
uint32_t lowbits = Endian_bigEndianToHost32(switchHeader->lowBits_be) << 7 >> 7;
switchHeader->lowBits_be = Endian_hostToBigEndian32(lowbits);
switchHeader->congestAndSuppressErrors = 1;
SwitchHeader_setVersion(switchHeader, 0);
#endif

Expand Down
2 changes: 1 addition & 1 deletion switch/PenaltyFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* + Switch Label +
* 4 | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* 8 | Congest |S| V | Penalty |
* 8 | Congest |S| V | | Penalty |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Penalty Breakdown
Expand Down
23 changes: 15 additions & 8 deletions switch/SwitchCore.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct SwitchInterface

struct SwitchCore* core;


struct Penalty* penalty;

struct Allocator_OnFreeJob* onFree;
};
Expand Down Expand Up @@ -79,7 +79,7 @@ static inline void sendError7(struct SwitchInterface* iface,
{
struct SwitchHeader* header = (struct SwitchHeader*) cause->bytes;

if (SwitchHeader_getMessageType(header) == SwitchHeader_TYPE_CONTROL
if (SwitchHeader_isV7Ctrl(header)
&& ((struct ErrorPacket7*) cause->bytes)->ctrl.type_be == Control_ERROR_be)
{
// Errors never cause other errors to be sent.
Expand All @@ -100,7 +100,7 @@ static inline void sendError7(struct SwitchInterface* iface,
SwitchHeader_setSuppressErrors(&err->switchHeader, true);
// set version to 0 so that other node will not change congestion field.
SwitchHeader_setVersion(&err->switchHeader, 0);
SwitchHeader_setPackedPenalty(&err->switchHeader, 0);
SwitchHeader_setPenalty(&err->switchHeader, 0);
SwitchHeader_setCongestion(&err->switchHeader, 0);

err->ctrl.type_be = Control_ERROR_be;
Expand Down Expand Up @@ -150,7 +150,7 @@ static inline void sendError8(struct SwitchInterface* iface,
err->switchHeader.label_be = Bits_bitReverse64(header->label_be);
SwitchHeader_setSuppressErrors(header, true);
SwitchHeader_setVersion(header, SwitchHeader_CURRENT_VERSION);
SwitchHeader_setPackedPenalty(header, 0);
SwitchHeader_setPenalty(header, 0);
SwitchHeader_setCongestion(header, 0);

err->handle = 0xffffffff;
Expand Down Expand Up @@ -292,8 +292,6 @@ static uint8_t receiveMessage(struct Message* message, struct Interface* iface)
uint64_t sourceLabel = Bits_bitReverse64(NumberCompress_getCompressed(sourceIndex, bits));
uint64_t targetLabel = (label >> bits) | sourceLabel;

header->label_be = Endian_hostToBigEndian64(targetLabel);

/* Too much noise.
Log_debug(sourceIf->core->logger,
"Forwarding packet ([%u] to [%u]), labels [0x%016" PRIx64 "] -> [0x%016" PRIx64 "]",
Expand All @@ -305,6 +303,17 @@ static uint8_t receiveMessage(struct Message* message, struct Interface* iface)
uint8_t messageClone[Control_Error_MAX_SIZE];
Bits_memcpy(messageClone, message->bytes, cloneLength);

// Update the header
header->label_be = Endian_hostToBigEndian64(targetLabel);
uint32_t labelShift = SwitchHeader_getLabelShift(header) + bits;
if (labelShift > 63) {
// TODO(cjd): hmm should we return an error packet?
Log_debug(sourceIf->core->logger, "Label rolled over");
return Error_NONE;
}
SwitchHeader_setLabelShift(header, labelShift);
Penalty_apply(sourceIf->penalty, header, message->length, );

const uint16_t err = sendMessage(&core->interfaces[destIndex], message, sourceIf->core->logger);
if (err) {
Log_debug(sourceIf->core->logger, "Sending packet caused an error [%s]",
Expand All @@ -317,8 +326,6 @@ static uint8_t receiveMessage(struct Message* message, struct Interface* iface)
Message_shift(message, Control_Error_MAX_SIZE, NULL);
Bits_memcpy(message->bytes, messageClone, cloneLength);
message->length = cloneLength;
header = (struct SwitchHeader*) message->bytes;
header->label_be = Endian_bigEndianToHost64(label);
sendError(sourceIf, message, err, sourceIf->core->logger);
return Error_NONE;
}
Expand Down
105 changes: 46 additions & 59 deletions wire/SwitchHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,9 @@
* + Switch Label +
* 4 | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* 8 | Congest |S| V | Penalty |
* 8 | Congest |S| V |labelShift | Penalty |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Penalty Breakdown (See PenaltyFloat.h)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Exponent | Penalty Mantissa |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* Penalty Breakdown (See PenaltyFloat.h)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |labelShift | exp | Mantissa |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Versions <= 7 byte number 8 is message type but the only 2 defined types were 0 (data)
* and 1 (control).
* Versions >= 8, byte number 8 is a congestion indicator but the lowest bit is a flag (S)
Expand All @@ -52,11 +42,10 @@
* Conveinently, all pre v8 versions will set the flag on every ctrl packet (including all errors).
* Versions >= 8 will set congest to non-zero as a way to tell themselves apart from versions < 8
* Versions < 8 are treating the byte as a number so all bits of congest will be zero.
* Version >= 11 labelShift is the number of bits which the label has been shifted to the right
* in the course of switching. Switches older than 11 will not update this value!
* Penalty is used for QoS, see Penalty.h
*/
#ifdef Version_7_COMPAT
#define SwitchHeader_TYPE_DATA 0
#define SwitchHeader_TYPE_CONTROL 1
#endif

#pragma pack(push)
#pragma pack(4)
Expand All @@ -68,13 +57,19 @@ struct SwitchHeader
/**
* Top 7 bits: congest
* Next bit: suppressErrors
*
* Bottom 24 bits: priority
* Anti-flooding, this is a big endian uint32_t with the high 8 bits cut off.
*
* This entire number is in big endian encoding.
* In versions <= 7, this byte was set to 0 for data and 1 for ctrl packets.
*/
uint8_t congestAndSuppressErrors;

/**
* High 2 bits: the version of the switch sending the packet.
* Low 6 bits: the number of bits which the label has been shifted in the process of switching
* the packet.
*/
uint32_t lowBits_be;
uint8_t versionAndLabelShift;

/** QoS Penalty, see Penalty.h */
uint16_t penalty_be;
};
#define SwitchHeader_SIZE 12
Assert_compileTime(sizeof(struct SwitchHeader) == SwitchHeader_SIZE);
Expand All @@ -86,72 +81,64 @@ Assert_compileTime(sizeof(struct SwitchHeader) == SwitchHeader_SIZE);

static inline uint32_t SwitchHeader_getVersion(const struct SwitchHeader* header)
{
return Endian_bigEndianToHost32(header->lowBits_be) << 8 >> 22;
return header->versionAndLabelShift >> 6;
}

static inline void SwitchHeader_setVersion(struct SwitchHeader* header, uint32_t version)
static inline bool SwitchHeader_isV7Ctrl(const struct SwitchHeader* header)
{
return !SwitchHeader_getVersion(header) && (header->congestAndSuppressErrors == 1);
}

static inline void SwitchHeader_setVersion(struct SwitchHeader* header, uint8_t version)
{
Assert_true(version < 4);
uint32_t lowBits = Endian_bigEndianToHost32(header->lowBits_be);
lowBits = (lowBits & 0xff3fffff) | version << 22;
header->lowBits_be = Endian_hostToBigEndian32(lowBits);
header->versionAndLabelShift =
(version << 6) | (header->versionAndLabelShift & SwitchHeader_MASK(6));
}

static inline uint32_t SwitchHeader_getLabelShift(const struct SwitchHeader* header)
{
return header->versionAndLabelShift & SwitchHeader_MASK(6);
}

static inline void SwitchHeader_setLabelShift(struct SwitchHeader* header, uint32_t shift)
{
Assert_true(shift < 64);
header->versionAndLabelShift = header->versionAndLabelShift >> 6 << 6;
header->versionAndLabelShift |= shift;
}

static inline uint32_t SwitchHeader_getCongestion(const struct SwitchHeader* header)
{
return Endian_bigEndianToHost32(header->lowBits_be) >> 25;
return header->congestAndSuppressErrors >> 1;
}

static inline void SwitchHeader_setCongestion(struct SwitchHeader* header, uint32_t cong)
{
Assert_true(cong <= 127);
if (!cong) { cong++; }
uint32_t lowBits = Endian_bigEndianToHost32(header->lowBits_be);
lowBits = (lowBits << 7 >> 7) | (cong << 25);
header->lowBits_be = Endian_hostToBigEndian32(lowBits);
header->congestAndSuppressErrors = (header->congestAndSuppressErrors & 1) | (cong << 1);
}

static inline uint32_t SwitchHeader_getPackedPenalty(const struct SwitchHeader* header)
static inline uint16_t SwitchHeader_getPenalty(const struct SwitchHeader* header)
{
return Endian_bigEndianToHost32(header->lowBits_be) & SwitchHeader_MASK(22);
return Endian_bigEndianToHost16(header->penalty_be);
}

static inline void SwitchHeader_setPackedPenalty(struct SwitchHeader* header,
uint32_t packedPenalty)
static inline void SwitchHeader_setPenalty(struct SwitchHeader* header, uint16_t penalty)
{
Assert_true(packedPenalty <= SwitchHeader_MASK(22));
uint32_t lowBits = Endian_bigEndianToHost32(header->lowBits_be);
lowBits = (lowBits >> 22 << 22) | packedPenalty;
header->lowBits_be = Endian_hostToBigEndian32(lowBits);
header->penalty_be = Endian_hostToBigEndian16(penalty);
}

static inline bool SwitchHeader_getSuppressErrors(const struct SwitchHeader* header)
{
return !!( Endian_hostToBigEndian32(1<<24) & header->lowBits_be );
return header->congestAndSuppressErrors & 1;
}

static inline void SwitchHeader_setSuppressErrors(struct SwitchHeader* header, bool suppress)
{
if (suppress) {
header->lowBits_be |= Endian_hostToBigEndian32(1<<24);
} else {
header->lowBits_be &= Endian_hostToBigEndian32(~(1<<24));
}
}

#ifdef Version_7_COMPAT
static inline void SwitchHeader_setPriorityAndMessageType(struct SwitchHeader* header,
const uint32_t priority,
const uint32_t messageType)
{
Assert_true(messageType < 2);
header->lowBits_be =
Endian_hostToBigEndian32( (priority & ((1 << 24) - 1)) | messageType << 24 );
header->congestAndSuppressErrors = header->congestAndSuppressErrors >> 1 << 1;
header->congestAndSuppressErrors |= suppress;
}
static inline uint32_t SwitchHeader_getMessageType(struct SwitchHeader* header)
{
return Endian_bigEndianToHost32(header->lowBits_be) >> 24;
}
#endif

#endif

0 comments on commit c9fe170

Please sign in to comment.