From e80cb826890a7dcdc5b0fc3127b59867d2e9c331 Mon Sep 17 00:00:00 2001 From: Eduard Grasa Date: Mon, 14 May 2018 09:18:31 +0200 Subject: [PATCH 01/40] kernel: added skeleton for rendezvous implementation --- kernel/dtcp-ps-default.c | 30 ++++++ kernel/dtcp-ps-default.h | 2 + kernel/dtcp-ps.h | 2 + kernel/dtcp.c | 133 +++++++++++++++++---------- kernel/dtcp.h | 1 + kernel/dtp.c | 61 +++++++++++- kernel/efcp-str.h | 13 +++ kernel/pci.c | 19 +++- kernel/pci.h | 48 +++++----- plugins/cong_avoidance/dtcp-ps-cas.c | 1 + plugins/dctcp/dtcp-ps-dctcp.c | 1 + plugins/dummy/dtcp-ps-dummy.c | 1 + plugins/rdsr-ps/cdrr/dtcp-ps-cdrr.c | 1 + plugins/red/dtcp-ps-red.c | 1 + 14 files changed, 239 insertions(+), 75 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 069e2422d6..723b18aabd 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -299,6 +299,35 @@ int default_rtt_estimator(struct dtcp_ps * ps, seq_num_t sn) return 0; } +int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) +{ + struct dtcp * dtcp; + + if (!ps) + return -1; + dtcp = ps->dm; + if (!dtcp) + return -1; + + LOG_DBG("Receiver rendezvous..."); + + /* TODO implement */ + /* Check Consistency of the Receiving Window values with the + * values in the PDU. + */ + + /* Send a ControlAck PDU to confirm reception of RendezvousPDU via + * lastControlPDU value or send any other control PDU with Flow Control + * information opening the window. + */ + + /* Receiver is in the Rendezvous-at-the-receiver state. The next PDU is + * expected to have DRF bit set to true + */ + + return 0; +} + struct ps_base * dtcp_ps_default_create(struct rina_component * component) { struct dtcp * dtcp = dtcp_from_component(component); @@ -333,6 +362,7 @@ struct ps_base * dtcp_ps_default_create(struct rina_component * component) ps->rcvr_control_ack = NULL; ps->no_rate_slow_down = NULL; ps->no_override_default_peak = NULL; + ps->rcvr_rendezvous = default_rcvr_rendezvous; return &ps->base; } diff --git a/kernel/dtcp-ps-default.h b/kernel/dtcp-ps-default.h index 3149eb7a2e..b1fc3213cd 100644 --- a/kernel/dtcp-ps-default.h +++ b/kernel/dtcp-ps-default.h @@ -55,4 +55,6 @@ int default_rate_reduction(struct dtcp_ps * ps, const struct pci * pci); int default_rtt_estimator(struct dtcp_ps * ps, seq_num_t sn); +int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci); + #endif /* RINA_DTCP_PS_COMMON_H */ diff --git a/kernel/dtcp-ps.h b/kernel/dtcp-ps.h index 41c51ea66c..1ad0719d61 100644 --- a/kernel/dtcp-ps.h +++ b/kernel/dtcp-ps.h @@ -81,6 +81,8 @@ struct dtcp_ps { int (* rcvr_control_ack)(struct dtcp_ps * instance); int (* no_rate_slow_down)(struct dtcp_ps * instance); int (* no_override_default_peak)(struct dtcp_ps * instance); + int (* rcvr_rendezvous)(struct dtcp_ps * instance, + const struct pci * pci); /* Parametric policies. */ bool flow_ctrl; diff --git a/kernel/dtcp.c b/kernel/dtcp.c index c968a3688a..84d97d30ba 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -261,6 +261,7 @@ static int populate_ctrl_pci(struct pci * pci, return -1; } return 0; + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: if (pci_control_last_seq_num_rcvd_set(pci, last_rcv_ctl_seq)) { LOG_ERR("Could not set last ctrl sn rcvd"); @@ -419,11 +420,12 @@ static int rcv_ack(struct dtcp * dtcp, return ret; } -static int rcv_flow_ctl(struct dtcp * dtcp, - struct du * du) +static int update_window_and_rate(struct dtcp * dtcp, + struct du * du) { uint_t rt; uint_t tf; + bool cancel_rv_timer; rt = pci_control_sndr_rate(&du->pci); tf = pci_control_time_frame(&du->pci); @@ -431,7 +433,7 @@ static int rcv_flow_ctl(struct dtcp * dtcp, spin_lock_bh(&dtcp->parent->sv_lock); if(dtcp_window_based_fctrl(dtcp->cfg)) { dtcp->sv->snd_rt_wind_edge = - pci_control_new_rt_wind_edge(&du->pci); + pci_control_new_rt_wind_edge(&du->pci); } if(dtcp_rate_based_fctrl(dtcp->cfg)) { @@ -444,11 +446,20 @@ static int rcv_flow_ctl(struct dtcp * dtcp, rt, tf); } } + + /* Check if rendezvous timer is active */ + cancel_rv_timer = false; + if (dtcp->sv->rendezvous_sndr) { + dtcp->sv->rendezvous_sndr = false; + cancel_rv_timer = true; + } spin_unlock_bh(&dtcp->parent->sv_lock); + if (cancel_rv_timer) + rtimer_stop(dtcp->parent->timers.rendezvous); + push_pdus_rmt(dtcp); - LOG_DBG("DTCP received FC (CPU: %d)", smp_processor_id()); dump_we(dtcp, &du->pci); du_destroy(du); @@ -456,13 +467,18 @@ static int rcv_flow_ctl(struct dtcp * dtcp, return 0; } +static int rcv_flow_ctl(struct dtcp * dtcp, + struct du * du) +{ + LOG_DBG("DTCP received FC (CPU: %d)", smp_processor_id()); + return update_window_and_rate(dtcp, du); +} + static int rcv_ack_and_flow_ctl(struct dtcp * dtcp, struct du * du) { struct dtcp_ps * ps; seq_num_t seq; - uint_t rt; - uint_t tf; seq = pci_control_ack_seq_num(&du->pci); @@ -476,37 +492,32 @@ static int rcv_ack_and_flow_ctl(struct dtcp * dtcp, LOG_ERR("Could not update RTXQ and LWE"); rcu_read_unlock(); - spin_lock_bh(&dtcp->parent->sv_lock); - if(dtcp_window_based_fctrl(dtcp->cfg)) { - dtcp->sv->snd_rt_wind_edge = - pci_control_new_rt_wind_edge(&du->pci); - LOG_DBG("Right Window Edge: %u", dtcp->sv->snd_rt_wind_edge); - } + LOG_DBG("DTCP received ACK-FC (CPU: %d)", smp_processor_id()); - if(dtcp_rate_based_fctrl(dtcp->cfg)) { - rt = pci_control_sndr_rate(&du->pci); - tf = pci_control_time_frame(&du->pci); + return update_window_and_rate(dtcp, du); +} - if(tf && rt) { - dtcp->sv->sndr_rate = rt; - dtcp->sv->time_unit = tf; - LOG_DBG("Rate based fields sets on flow ctl and " - "ack, rate: %u, time: %u", - rt, tf); - } - } - spin_unlock_bh(&dtcp->parent->sv_lock); +static int rcvr_rendezvous(struct dtcp * dtcp, + struct du * du) +{ + struct dtcp_ps * ps; + int ret; - LOG_DBG("Calling CWQ_deliver for DTCP: %pK", dtcp); - push_pdus_rmt(dtcp); + rcu_read_lock(); + ps = container_of(rcu_dereference(dtcp->base.ps), + struct dtcp_ps, base); + if (ps->rcvr_rendezvous) + ret = ps->rcvr_rendezvous(ps, &du->pci); + else + ret = 0; + rcu_read_unlock(); - /* FIXME: Verify values for the receiver side */ - LOG_DBG("DTCP received ACK-FC (CPU: %d)", smp_processor_id()); + LOG_INFO("DTCP received Rendezvous (CPU: %d)", smp_processor_id()); dump_we(dtcp, &du->pci); du_destroy(du); - return 0; + return ret; } int dtcp_common_rcv_control(struct dtcp * dtcp, struct du * du) @@ -587,6 +598,9 @@ int dtcp_common_rcv_control(struct dtcp * dtcp, struct du * du) case PDU_TYPE_ACK_AND_FC: ret = rcv_ack_and_flow_ctl(dtcp, du); break; + case PDU_TYPE_RENDEZVOUS: + ret = rcvr_rendezvous(dtcp, du); + break; default: ret = -1; break; @@ -687,13 +701,35 @@ pdu_type_t pdu_ctrl_type_get(struct dtcp * dtcp, seq_num_t seq) } EXPORT_SYMBOL(pdu_ctrl_type_get); -int dtcp_ack_flow_control_pdu_send(struct dtcp * dtcp, seq_num_t seq) +static int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type) { struct du * du; - pdu_type_t type; - seq_num_t dbg_seq_num; + du = pdu_ctrl_generate(dtcp, type); + if (!du) { + atomic_dec(&dtcp->cpdus_in_transit); + return -1; + } + + dbg_seq_num = pci_sequence_number_get(&du->pci); + + if (dtcp_pdu_send(dtcp, du)){ + atomic_dec(&dtcp->cpdus_in_transit); + return -1; + } + + dump_we(dtcp, &du->pci); + + atomic_dec(&dtcp->cpdus_in_transit); + + return 0; +} + +int dtcp_ack_flow_control_pdu_send(struct dtcp * dtcp, seq_num_t seq) +{ + pdu_type_t type; + if (!dtcp) { LOG_ERR("No instance passed, cannot run policy"); return -1; @@ -707,28 +743,20 @@ int dtcp_ack_flow_control_pdu_send(struct dtcp * dtcp, seq_num_t seq) return 0; } - du = pdu_ctrl_generate(dtcp, type); - if (!du) { - atomic_dec(&dtcp->cpdus_in_transit); - return -1; - } - - dbg_seq_num = pci_sequence_number_get(&du->pci); - - LOG_DBG("DTCP Sending ACK %u (CPU: %d)", dbg_seq_num, smp_processor_id()); - dump_we(dtcp, &du->pci); - - if (dtcp_pdu_send(dtcp, du)){ - atomic_dec(&dtcp->cpdus_in_transit); - return -1; - } - - atomic_dec(&dtcp->cpdus_in_transit); + LOG_DBG("DTCP Sending ACK (CPU: %d)", smp_processor_id()); - return 0; + return ctrl_pdu_send(dtcp, type); } EXPORT_SYMBOL(dtcp_ack_flow_control_pdu_send); +int dtcp_rendezvous_pdu_send(struct dtcp * dtcp) +{ + atomic_inc(&dtcp->cpdus_in_transit); + LOG_DBG("DTCP Sending Rendezvous (CPU: %d)", smp_processor_id()); + return ctrl_pdu_send(dtcp, PDU_TYPE_RENDEZVOUS); +} +EXPORT_SYMBOL(dtcp_rendezvous_pdu_send); + static struct dtcp_sv default_sv = { .pdus_per_time_unit = 0, .next_snd_ctl_seq = 0, @@ -750,6 +778,8 @@ static struct dtcp_sv default_sv = { .flow_ctl = 0, .rtt = 0, .srtt = 0, + .rendezvous_sndr = false, + .rendezvous_rcvr = false, }; /* FIXME: this should be completed with other parameters from the config */ @@ -914,6 +944,9 @@ int dtcp_select_policy_set(struct dtcp * dtcp, if (!ps->rtt_estimator) { ps->rtt_estimator = default_rtt_estimator; } + if (!ps->rcvr_rendezvous) { + ps->rcvr_rendezvous = default_rcvr_rendezvous; + } } base_select_policy_set_finish(&dtcp->base, &trans); diff --git a/kernel/dtcp.h b/kernel/dtcp.h index 4f58dfdafb..b7a1bd0a7a 100644 --- a/kernel/dtcp.h +++ b/kernel/dtcp.h @@ -54,6 +54,7 @@ int dtcp_common_rcv_control(struct dtcp * dtcp, /* Used by DTP to have an ack-control PDU sent by DTCP */ int dtcp_ack_flow_control_pdu_send(struct dtcp * instance, seq_num_t seq); +int dtcp_rendezvous_pdu_send(struct dtcp * instance); /* begin SDK */ int dtcp_select_policy_set(struct dtcp * dtcp, const string_t *path, diff --git a/kernel/dtp.c b/kernel/dtp.c index e43023ed87..d6a8c3dca2 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -476,6 +476,39 @@ static void tf_receiver_inactivity(void * data) return; } +/* Runs the Rendezvous timer */ +static void tf_rendezvous(void * data) +{ + struct dtp * dtp; + bool start_rv_timer; + timeout_t rv; + + LOG_DBG("Running rendezvous timer..."); + dtp = (struct dtp *) data; + if (!dtp) { + LOG_ERR("No dtp to work with"); + return; + } + + /* Check if rendezvous PDU needs to be send*/ + start_rv_timer = false; + spin_lock_bh(&dtp->sv_lock); + if (dtp->dtcp->sv->rendezvous_sndr) { + /* Start rendezvous timer, wait for 2*RTT to fire */ + start_rv_timer = true; + rv = 2*dtp->dtcp->sv->rtt; + } + spin_unlock_bh(&dtp->sv_lock); + + if (start_rv_timer) { + /* Send rendezvous PDU and start timer */ + dtcp_rendezvous_pdu_send(dtp->dtcp); + rtimer_start(dtp->timers.rendezvous, rv); + } + + return; +} + /* * NOTE: * AF is the factor to which A is divided in order to obtain the @@ -1001,10 +1034,12 @@ struct dtp * dtp_create(struct efcp * efcp, rtimer_create(tf_receiver_inactivity, dtp); dtp->timers.a = rtimer_create(tf_a, dtp); dtp->timers.rate_window = rtimer_create(tf_rate_window, dtp); + dtp->timers.rendezvous = rtimer_create(tf_rendezvous, dtp); if (!dtp->timers.sender_inactivity || !dtp->timers.receiver_inactivity || !dtp->timers.a || - !dtp->timers.rate_window) { + !dtp->timers.rate_window || + !dtp->timers.rendezvous) { dtp_destroy(dtp); return NULL; } @@ -1109,6 +1144,8 @@ int dtp_destroy(struct dtp * instance) rtimer_destroy(instance->timers.receiver_inactivity); if (instance->timers.rate_window) rtimer_destroy(instance->timers.rate_window); + if (instance->timers.rendezvous) + rtimer_destroy(instance->timers.rendezvous); if (instance->to_post) ringq_destroy(instance->to_post, (void (*)(void *)) du_destroy); if (instance->to_send) ringq_destroy(instance->to_send, @@ -1179,7 +1216,8 @@ int dtp_write(struct dtp * instance, struct efcp * efcp; int sbytes; uint_t sc; - timeout_t mpl, r, a; + timeout_t mpl, r, a, rv; + bool start_rv_timer; efcp = instance->efcp; dtcp = instance->dtcp; @@ -1265,6 +1303,25 @@ int dtp_write(struct dtp * instance, goto stats_err_exit; } rcu_read_unlock(); + + /* Check if rendezvous PDU needs to be send*/ + start_rv_timer = false; + spin_lock_bh(&instance->sv_lock); + if (!instance->dtcp->sv->rendezvous_sndr) { + instance->dtcp->sv->rendezvous_sndr = true; + + /* Start rendezvous timer, wait for 2*RTT to fire */ + start_rv_timer = true; + rv = 2*instance->dtcp->sv->rtt; + } + spin_unlock_bh(&instance->sv_lock); + + if (start_rv_timer) { + /* Send rendezvous PDU and start time */ + dtcp_rendezvous_pdu_send(instance->dtcp); + rtimer_start(instance->timers.rendezvous, rv); + } + return 0; } if(instance->sv->rate_based) { diff --git a/kernel/efcp-str.h b/kernel/efcp-str.h index ba55aa68a1..65668108ed 100644 --- a/kernel/efcp-str.h +++ b/kernel/efcp-str.h @@ -168,6 +168,7 @@ struct dtp { struct rtimer * receiver_inactivity; struct rtimer * a; struct rtimer * rate_window; + struct rtimer * rendezvous; } timers; struct robject robj; @@ -280,6 +281,18 @@ struct dtcp_sv { uint_t rtt; uint_t srtt; uint_t rttvar; + + /* Rendezvous */ + + /* This Boolean indicates whether there is a zero-length window and a + * Rendezvous PDU has been sent. + */ + bool rendezvous_sndr; + + /* This Boolean indicates whether a Rendezvous PDU was received. The + * next DT-PDU is expected to have a DRF bit set to true. + */ + bool rendezvous_rcvr; }; struct dtcp { diff --git a/kernel/pci.c b/kernel/pci.c index 1b4d9a9d89..d2ec6a5800 100644 --- a/kernel/pci.c +++ b/kernel/pci.c @@ -37,7 +37,6 @@ #define FLAGS_SIZE 1 #define TYPE_SIZE 1 - enum pci_field_index { PCI_BASE_VERSION = 0, PCI_BASE_DST_ADD, @@ -82,6 +81,8 @@ enum pci_field_index { PCI_ACK_FC_SNDR_RATE, PCI_ACK_FC_TIME_FRAME, PCI_ACK_FC_SIZE, + /* pci_rvous */ + PCI_RVOUS_SIZE, /* number of fields */ PCI_FIELD_INDEX_MAX, }; @@ -193,6 +194,7 @@ ssize_t *pci_offset_table_create(struct dt_cons *dt_cons) case PCI_FC_SIZE: case PCI_CACK_SIZE: case PCI_ACK_SIZE: + case PCI_RVOUS_SIZE: case PCI_ACK_FC_SIZE: offset = base_offset; break; @@ -236,6 +238,7 @@ ssize_t *pci_offset_table_create(struct dt_cons *dt_cons) LOG_DBG("pci_offsets[PCI_ACK_FC_MY_RWE] = %zu", pci_offsets[PCI_ACK_FC_MY_RWE]); LOG_DBG("pci_offsets[PCI_ACK_FC_SNDR_RATE] = %zu", pci_offsets[PCI_ACK_FC_SNDR_RATE]); LOG_DBG("pci_offsets[PCI_ACK_FC_TIME_FRAME] = %zu", pci_offsets[PCI_ACK_FC_TIME_FRAME]); + LOG_DBG("pci_offsets[PCI_RVOUS_SIZE] = %zu", pci_offsets[PCI_RVOUS_SIZE]); LOG_DBG("pci_offsets[PCI_ACK_FC_SIZE] = %zu",pci_offsets[PCI_ACK_FC_SIZE]); return pci_offsets; } @@ -450,6 +453,8 @@ ssize_t pci_calculate_size(struct efcp_config *cfg, pdu_type_t type) return cfg->pci_offset_table[PCI_ACK_FC_SIZE]; case PDU_TYPE_CACK: return cfg->pci_offset_table[PCI_CACK_SIZE]; + case PDU_TYPE_RENDEZVOUS: + return cfg->pci_offset_table[PCI_RVOUS_SIZE]; default: return -1; } @@ -490,6 +495,7 @@ seq_num_t pci_control_new_rt_wind_edge(const struct pci *pci) switch (pci_type(pci)) { case PDU_TYPE_FC: PCI_GETTER(pci, PCI_FC_NEW_RWE, seq_num_length, seq_num_t); + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_GETTER(pci, PCI_CACK_NEW_RWE, seq_num_length, seq_num_t); case PDU_TYPE_ACK_AND_FC: @@ -503,6 +509,7 @@ EXPORT_SYMBOL(pci_control_new_rt_wind_edge); seq_num_t pci_control_new_left_wind_edge(const struct pci *pci) { switch (pci_type(pci)) { + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_GETTER(pci, PCI_CACK_NEW_LWE, seq_num_length, seq_num_t); case PDU_TYPE_ACK_AND_FC: @@ -518,6 +525,7 @@ seq_num_t pci_control_my_rt_wind_edge(const struct pci *pci) switch (pci_type(pci)) { case PDU_TYPE_FC: PCI_GETTER(pci, PCI_FC_MY_RWE, seq_num_length, seq_num_t); + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_GETTER(pci, PCI_CACK_MY_RWE, seq_num_length, seq_num_t); case PDU_TYPE_ACK_AND_FC: @@ -533,6 +541,7 @@ seq_num_t pci_control_my_left_wind_edge(const struct pci *pci) switch (pci_type(pci)) { case PDU_TYPE_FC: PCI_GETTER(pci, PCI_FC_MY_LWE, seq_num_length, seq_num_t); + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_GETTER(pci, PCI_CACK_MY_LWE, seq_num_length, seq_num_t); case PDU_TYPE_ACK_AND_FC: @@ -546,6 +555,7 @@ EXPORT_SYMBOL(pci_control_my_left_wind_edge); seq_num_t pci_control_last_seq_num_rcvd(const struct pci *pci) { switch (pci_type(pci)) { + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_GETTER(pci, PCI_CACK_LAST_CSN_RCVD, seq_num_length, seq_num_t); case PDU_TYPE_ACK_AND_FC: @@ -561,6 +571,7 @@ u_int32_t pci_control_sndr_rate(const struct pci *pci) switch (pci_type(pci)) { case PDU_TYPE_FC: PCI_GETTER(pci, PCI_FC_SNDR_RATE, rate_length, u_int32_t); + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_GETTER(pci, PCI_CACK_SNDR_RATE, rate_length, u_int32_t); case PDU_TYPE_ACK_AND_FC: @@ -605,6 +616,7 @@ int pci_control_new_rt_wind_edge_set(struct pci *pci, seq_num_t seq) switch (pci_type(pci)) { case PDU_TYPE_FC: PCI_SETTER(pci, PCI_FC_NEW_RWE, seq_num_length, seq); + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_SETTER(pci, PCI_CACK_NEW_RWE, seq_num_length, seq); case PDU_TYPE_ACK_AND_FC: @@ -618,6 +630,7 @@ EXPORT_SYMBOL(pci_control_new_rt_wind_edge_set); int pci_control_new_left_wind_edge_set(struct pci *pci, seq_num_t seq) { switch (pci_type(pci)) { + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_SETTER(pci, PCI_CACK_NEW_LWE, seq_num_length, seq); case PDU_TYPE_ACK_AND_FC: @@ -633,6 +646,7 @@ int pci_control_my_rt_wind_edge_set(struct pci *pci, seq_num_t seq) switch (pci_type(pci)) { case PDU_TYPE_FC: PCI_SETTER(pci, PCI_FC_MY_RWE, seq_num_length, seq); + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_SETTER(pci, PCI_CACK_MY_RWE, seq_num_length, seq); case PDU_TYPE_ACK_AND_FC: @@ -648,6 +662,7 @@ int pci_control_my_left_wind_edge_set(struct pci *pci, seq_num_t seq) switch (pci_type(pci)) { case PDU_TYPE_FC: PCI_SETTER(pci, PCI_FC_MY_LWE, seq_num_length, seq); + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_SETTER(pci, PCI_CACK_MY_LWE, seq_num_length, seq); case PDU_TYPE_ACK_AND_FC: @@ -661,6 +676,7 @@ EXPORT_SYMBOL(pci_control_my_left_wind_edge_set); int pci_control_last_seq_num_rcvd_set(struct pci *pci, seq_num_t seq) { switch (pci_type(pci)) { + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_SETTER(pci, PCI_CACK_LAST_CSN_RCVD, seq_num_length, seq); case PDU_TYPE_ACK_AND_FC: @@ -676,6 +692,7 @@ int pci_control_sndr_rate_set(struct pci *pci, u_int32_t rate) switch (pci_type(pci)) { case PDU_TYPE_FC: PCI_SETTER(pci, PCI_FC_SNDR_RATE, rate_length, rate); + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_CACK: PCI_SETTER(pci, PCI_CACK_SNDR_RATE, rate_length, rate); case PDU_TYPE_ACK_AND_FC: diff --git a/kernel/pci.h b/kernel/pci.h index fe8b5de0f0..2d9c52b374 100644 --- a/kernel/pci.h +++ b/kernel/pci.h @@ -51,6 +51,8 @@ typedef uint8_t pdu_flags_t; #define PDU_TYPE_SNACK 0xCA /* Selective NACK */ #define PDU_TYPE_SACK_AND_FC 0xCD /* Selective ACK and Flow Control */ #define PDU_TYPE_SNACK_AND_FC 0xCE /* Selective NACK and Flow Control */ +/* Rendezvous PDU */ +#define PDU_TYPE_RENDEZVOUS 0xCF /* Rendezvous */ /* Management PDUs */ #define PDU_TYPE_MGMT 0x40 /* Management */ /* Number of different PDU types */ @@ -58,29 +60,31 @@ typedef uint8_t pdu_flags_t; typedef uint8_t pdu_type_t; -#define pdu_type_is_ok(X) \ - ((X == PDU_TYPE_DT) ? true : \ - ((X == PDU_TYPE_CACK) ? true : \ - ((X == PDU_TYPE_SACK) ? true : \ - ((X == PDU_TYPE_NACK) ? true : \ - ((X == PDU_TYPE_FC) ? true : \ - ((X == PDU_TYPE_ACK) ? true : \ - ((X == PDU_TYPE_ACK_AND_FC) ? true : \ - ((X == PDU_TYPE_SACK_AND_FC) ? true : \ - ((X == PDU_TYPE_SNACK_AND_FC) ? true : \ - ((X == PDU_TYPE_MGMT) ? true : \ - false)))))))))) +#define pdu_type_is_ok(X) \ + ((X == PDU_TYPE_DT) ? true : \ + ((X == PDU_TYPE_CACK) ? true : \ + ((X == PDU_TYPE_SACK) ? true : \ + ((X == PDU_TYPE_NACK) ? true : \ + ((X == PDU_TYPE_FC) ? true : \ + ((X == PDU_TYPE_ACK) ? true : \ + ((X == PDU_TYPE_ACK_AND_FC) ? true : \ + ((X == PDU_TYPE_SACK_AND_FC) ? true : \ + ((X == PDU_TYPE_SNACK_AND_FC) ? true : \ + ((X == PDU_TYPE_RENDEZVOUS) ? true : \ + ((X == PDU_TYPE_MGMT) ? true : \ + false))))))))))) -#define pdu_type_is_control(X) \ - ((X == PDU_TYPE_CACK) ? true : \ - ((X == PDU_TYPE_SACK) ? true : \ - ((X == PDU_TYPE_NACK) ? true : \ - ((X == PDU_TYPE_FC) ? true : \ - ((X == PDU_TYPE_ACK) ? true : \ - ((X == PDU_TYPE_ACK_AND_FC) ? true : \ - ((X == PDU_TYPE_SACK_AND_FC) ? true : \ - ((X == PDU_TYPE_SNACK_AND_FC) ? true : \ - false)))))))) +#define pdu_type_is_control(X) \ + ((X == PDU_TYPE_CACK) ? true : \ + ((X == PDU_TYPE_SACK) ? true : \ + ((X == PDU_TYPE_NACK) ? true : \ + ((X == PDU_TYPE_FC) ? true : \ + ((X == PDU_TYPE_ACK) ? true : \ + ((X == PDU_TYPE_ACK_AND_FC) ? true : \ + ((X == PDU_TYPE_SACK_AND_FC) ? true : \ + ((X == PDU_TYPE_RENDEZVOUS) ? true : \ + ((X == PDU_TYPE_SNACK_AND_FC) ? true : \ + false))))))))) struct pci { unsigned char *h; /* do not move from 1st position */ diff --git a/plugins/cong_avoidance/dtcp-ps-cas.c b/plugins/cong_avoidance/dtcp-ps-cas.c index 0cd371f99c..67fa6b1755 100644 --- a/plugins/cong_avoidance/dtcp-ps-cas.c +++ b/plugins/cong_avoidance/dtcp-ps-cas.c @@ -250,6 +250,7 @@ dtcp_ps_cas_create(struct rina_component * component) ps->rcvr_control_ack = NULL; ps->no_rate_slow_down = NULL; ps->no_override_default_peak = NULL; + ps->rcvr_rendezvous = NULL; return &ps->base; } diff --git a/plugins/dctcp/dtcp-ps-dctcp.c b/plugins/dctcp/dtcp-ps-dctcp.c index 21dbe70322..181d95d1e8 100644 --- a/plugins/dctcp/dtcp-ps-dctcp.c +++ b/plugins/dctcp/dtcp-ps-dctcp.c @@ -164,6 +164,7 @@ static struct ps_base * dtcp_ps_dctcp_create(struct rina_component * component) ps->rcvr_control_ack = NULL; ps->no_rate_slow_down = NULL; ps->no_override_default_peak = NULL; + ps->rcvr_rendezvous = NULL; LOG_INFO("DCTCP DTCP policy created, shift_g value is %d", data->shift_g); diff --git a/plugins/dummy/dtcp-ps-dummy.c b/plugins/dummy/dtcp-ps-dummy.c index 4b1c4fdb6a..92a6a6ec2c 100644 --- a/plugins/dummy/dtcp-ps-dummy.c +++ b/plugins/dummy/dtcp-ps-dummy.c @@ -113,6 +113,7 @@ dtcp_ps_dummy_create(struct rina_component * component) ps->rcvr_control_ack = NULL; ps->no_rate_slow_down = NULL; ps->no_override_default_peak = NULL; + ps->rcvr_rendezvous = NULL; return &ps->base; } diff --git a/plugins/rdsr-ps/cdrr/dtcp-ps-cdrr.c b/plugins/rdsr-ps/cdrr/dtcp-ps-cdrr.c index 186ad80ae5..1f53d0ba83 100644 --- a/plugins/rdsr-ps/cdrr/dtcp-ps-cdrr.c +++ b/plugins/rdsr-ps/cdrr/dtcp-ps-cdrr.c @@ -483,6 +483,7 @@ static struct ps_base * cdrr_create(struct rina_component * component) { ps->rcvr_control_ack = NULL; ps->no_rate_slow_down = NULL; ps->no_override_default_peak = NULL; + ps->rcvr_rendezvous = NULL; ri = rkzalloc(sizeof(struct cdrr_rate_info), GFP_KERNEL); diff --git a/plugins/red/dtcp-ps-red.c b/plugins/red/dtcp-ps-red.c index ae1406b529..131acf3f16 100644 --- a/plugins/red/dtcp-ps-red.c +++ b/plugins/red/dtcp-ps-red.c @@ -147,6 +147,7 @@ dtcp_ps_red_create(struct rina_component * component) ps->rcvr_control_ack = NULL; ps->no_rate_slow_down = NULL; ps->no_override_default_peak = NULL; + ps->rcvr_rendezvous = NULL; return &ps->base; } From d6a4b461b7e1a5d0fe0b74d6084c183f8a3ef023 Mon Sep 17 00:00:00 2001 From: Eduard Grasa Date: Tue, 15 May 2018 11:22:32 +0200 Subject: [PATCH 02/40] kernel: dtp/dtcp: first version of rendezvous implementation --- kernel/dtcp-ps-default.c | 60 +++++++++++++++++++++++++++++++++++----- kernel/dtcp.c | 3 +- kernel/dtp.c | 3 +- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 723b18aabd..5c4d12e1d2 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -302,6 +302,8 @@ int default_rtt_estimator(struct dtcp_ps * ps, seq_num_t sn) int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) { struct dtcp * dtcp; + struct du * du; + seq_num_t rcv_lft, rcv_rt, snd_lft, snd_rt; if (!ps) return -1; @@ -309,21 +311,65 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) if (!dtcp) return -1; - LOG_DBG("Receiver rendezvous..."); + LOG_INFO("Receiver rendezvous..."); - /* TODO implement */ - /* Check Consistency of the Receiving Window values with the - * values in the PDU. + spin_lock_bh(&dtcp->parent->sv_lock); + if (!dtcp->sv->flow_ctl) { + LOG_WARN("Received Rendezvous PDU with flow control disabled"); + spin_unlock_bh(&dtcp->parent->sv_lock); + return 0; + } + + /* TODO: check if retransmission control enabled */ + + if (dtcp->parent->sv->window_based) { + rcv_lft = pci_control_new_left_wind_edge(pci); + rcv_rt = pci_control_new_rt_wind_edge(pci); + snd_lft = pci_control_my_left_wind_edge(pci); + snd_rt = pci_control_my_rt_wind_edge(pci); + + /* Check Consistency of the Receiving Window values with the + * values in the PDU. + */ + if (dtcp->sv->snd_lft_win != rcv_lft) { + /* TODO what to do? */ + } + + if (dtcp->sv->snd_rt_wind_edge != rcv_rt) { + /* TODO what to do? */ + } + + if (dtcp->parent->sv->rcv_left_window_edge != snd_lft) { + LOG_INFO("Credit difference is %d", + snd_lft - dtcp->parent->sv->rcv_left_window_edge); + dtcp->parent->sv->rcv_left_window_edge = snd_lft; + dtcp->sv->rcvr_rt_wind_edge = snd_lft + dtcp->sv->rcvr_credit; + } + } + + if (dtcp->sv->flow_ctl && dtcp->parent->sv->rate_based) { + /* TODO implement */ + } + + /* TODO Receiver is in the Rendezvous-at-the-receiver state. The next PDU is + * expected to have DRF bit set to true */ + spin_unlock_bh(&dtcp->parent->sv_lock); + /* Send a ControlAck PDU to confirm reception of RendezvousPDU via * lastControlPDU value or send any other control PDU with Flow Control * information opening the window. */ + du = pdu_ctrl_generate(dtcp, PDU_TYPE_FC); + if (!du) + return -1; - /* Receiver is in the Rendezvous-at-the-receiver state. The next PDU is - * expected to have DRF bit set to true - */ + LOG_INFO("DTCP Sending FC (CPU: %d)", smp_processor_id()); + dump_we(dtcp, &du->pci); + + if (dtcp_pdu_send(dtcp, du)) + return -1; return 0; } diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 84d97d30ba..b7edcf72a6 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -452,6 +452,7 @@ static int update_window_and_rate(struct dtcp * dtcp, if (dtcp->sv->rendezvous_sndr) { dtcp->sv->rendezvous_sndr = false; cancel_rv_timer = true; + LOG_INFO("Stopping rendezvous timer"); } spin_unlock_bh(&dtcp->parent->sv_lock); @@ -752,7 +753,7 @@ EXPORT_SYMBOL(dtcp_ack_flow_control_pdu_send); int dtcp_rendezvous_pdu_send(struct dtcp * dtcp) { atomic_inc(&dtcp->cpdus_in_transit); - LOG_DBG("DTCP Sending Rendezvous (CPU: %d)", smp_processor_id()); + LOG_INFO("DTCP Sending Rendezvous (CPU: %d)", smp_processor_id()); return ctrl_pdu_send(dtcp, PDU_TYPE_RENDEZVOUS); } EXPORT_SYMBOL(dtcp_rendezvous_pdu_send); diff --git a/kernel/dtp.c b/kernel/dtp.c index d6a8c3dca2..08303b975d 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -483,7 +483,7 @@ static void tf_rendezvous(void * data) bool start_rv_timer; timeout_t rv; - LOG_DBG("Running rendezvous timer..."); + LOG_INFO("Running rendezvous timer..."); dtp = (struct dtp *) data; if (!dtp) { LOG_ERR("No dtp to work with"); @@ -1318,7 +1318,6 @@ int dtp_write(struct dtp * instance, if (start_rv_timer) { /* Send rendezvous PDU and start time */ - dtcp_rendezvous_pdu_send(instance->dtcp); rtimer_start(instance->timers.rendezvous, rv); } From f00f6ede27ea2c56a76b7103885c3e96d803a500 Mon Sep 17 00:00:00 2001 From: Eduard Grasa Date: Tue, 15 May 2018 12:32:49 +0200 Subject: [PATCH 03/40] kernel: dtp/dtcp: fixed bugs in rendezvous --- kernel/dtcp.c | 24 +++++++++++++++--------- kernel/dtp.c | 10 +++++----- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index b7edcf72a6..8e08259195 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -702,10 +702,9 @@ pdu_type_t pdu_ctrl_type_get(struct dtcp * dtcp, seq_num_t seq) } EXPORT_SYMBOL(pdu_ctrl_type_get); -static int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type) +static int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) { struct du * du; - seq_num_t dbg_seq_num; du = pdu_ctrl_generate(dtcp, type); if (!du) { @@ -713,11 +712,18 @@ static int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type) return -1; } - dbg_seq_num = pci_sequence_number_get(&du->pci); - - if (dtcp_pdu_send(dtcp, du)){ - atomic_dec(&dtcp->cpdus_in_transit); - return -1; + if (direct) { + if (dtp_pdu_send(dtcp->parent, dtcp->rmt, du)){ + atomic_dec(&dtcp->cpdus_in_transit); + du_destroy(du); + return -1; + } + } else { + if (dtcp_pdu_send(dtcp, du)){ + atomic_dec(&dtcp->cpdus_in_transit); + du_destroy(du); + return -1; + } } dump_we(dtcp, &du->pci); @@ -746,7 +752,7 @@ int dtcp_ack_flow_control_pdu_send(struct dtcp * dtcp, seq_num_t seq) LOG_DBG("DTCP Sending ACK (CPU: %d)", smp_processor_id()); - return ctrl_pdu_send(dtcp, type); + return ctrl_pdu_send(dtcp, type, false); } EXPORT_SYMBOL(dtcp_ack_flow_control_pdu_send); @@ -754,7 +760,7 @@ int dtcp_rendezvous_pdu_send(struct dtcp * dtcp) { atomic_inc(&dtcp->cpdus_in_transit); LOG_INFO("DTCP Sending Rendezvous (CPU: %d)", smp_processor_id()); - return ctrl_pdu_send(dtcp, PDU_TYPE_RENDEZVOUS); + return ctrl_pdu_send(dtcp, PDU_TYPE_RENDEZVOUS, true); } EXPORT_SYMBOL(dtcp_rendezvous_pdu_send); diff --git a/kernel/dtp.c b/kernel/dtp.c index 08303b975d..7f58634000 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -43,7 +43,7 @@ #include "efcp-str.h" #define TO_POST_LENGTH 1000 -#define TO_SEND_LENGTH 16 +#define TO_SEND_LENGTH 50 static struct policy_set_list policy_sets = { .head = LIST_HEAD_INIT(policy_sets.head) @@ -494,9 +494,9 @@ static void tf_rendezvous(void * data) start_rv_timer = false; spin_lock_bh(&dtp->sv_lock); if (dtp->dtcp->sv->rendezvous_sndr) { - /* Start rendezvous timer, wait for 2*RTT to fire */ + /* Start rendezvous timer, wait for Tr to fire */ start_rv_timer = true; - rv = 2*dtp->dtcp->sv->rtt; + rv = dtp->sv->tr; } spin_unlock_bh(&dtp->sv_lock); @@ -1310,9 +1310,9 @@ int dtp_write(struct dtp * instance, if (!instance->dtcp->sv->rendezvous_sndr) { instance->dtcp->sv->rendezvous_sndr = true; - /* Start rendezvous timer, wait for 2*RTT to fire */ + /* Start rendezvous timer, wait for Tr to fire */ start_rv_timer = true; - rv = 2*instance->dtcp->sv->rtt; + rv = instance->sv->tr; } spin_unlock_bh(&instance->sv_lock); From c92c7f78ce518dbe98764690bcdef76eba635b55 Mon Sep 17 00:00:00 2001 From: Eduard Grasa Date: Tue, 15 May 2018 12:53:13 +0200 Subject: [PATCH 04/40] kernel: rmt: missed rendezvous pdu matching --- kernel/dtp.c | 2 +- kernel/rmt.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/dtp.c b/kernel/dtp.c index 7f58634000..274ab852b9 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -43,7 +43,7 @@ #include "efcp-str.h" #define TO_POST_LENGTH 1000 -#define TO_SEND_LENGTH 50 +#define TO_SEND_LENGTH 16 static struct policy_set_list policy_sets = { .head = LIST_HEAD_INIT(policy_sets.head) diff --git a/kernel/rmt.c b/kernel/rmt.c index 813d4e48fe..4f5b1f0359 100644 --- a/kernel/rmt.c +++ b/kernel/rmt.c @@ -1347,6 +1347,7 @@ int rmt_receive(struct rmt *rmt, case PDU_TYPE_FC: case PDU_TYPE_ACK: case PDU_TYPE_ACK_AND_FC: + case PDU_TYPE_RENDEZVOUS: case PDU_TYPE_DT: /* * (FUTURE) From 396afebc6c418960eab50ca89699e4c2a385d0c0 Mon Sep 17 00:00:00 2001 From: Eduard Grasa Date: Tue, 15 May 2018 13:13:22 +0200 Subject: [PATCH 05/40] kernel: efcp: fixed bugs in rendezvous --- kernel/dtcp-ps-default.c | 6 ----- kernel/dtcp.c | 3 +++ kernel/dtp.c | 50 ++++++++++++++++++---------------------- kernel/dtp.h | 2 ++ 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 5c4d12e1d2..64533b0d70 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -314,12 +314,6 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) LOG_INFO("Receiver rendezvous..."); spin_lock_bh(&dtcp->parent->sv_lock); - if (!dtcp->sv->flow_ctl) { - LOG_WARN("Received Rendezvous PDU with flow control disabled"); - spin_unlock_bh(&dtcp->parent->sv_lock); - return 0; - } - /* TODO: check if retransmission control enabled */ if (dtcp->parent->sv->window_based) { diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 8e08259195..5f4b060f5a 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -608,6 +608,9 @@ int dtcp_common_rcv_control(struct dtcp * dtcp, struct du * du) } atomic_dec(&dtcp->cpdus_in_transit); + + dtp_send_pending_ctrl_pdus(dtcp->parent); + return ret; } diff --git a/kernel/dtp.c b/kernel/dtp.c index 274ab852b9..4aafbec706 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -496,7 +496,7 @@ static void tf_rendezvous(void * data) if (dtp->dtcp->sv->rendezvous_sndr) { /* Start rendezvous timer, wait for Tr to fire */ start_rv_timer = true; - rv = dtp->sv->tr; + rv = jiffies_to_msecs(dtp->sv->tr); } spin_unlock_bh(&dtp->sv_lock); @@ -663,13 +663,8 @@ static void tf_a(void * o) LOG_ERR("sending_ack failed"); rtimer_start(dtp->timers.a, a/AF); } - while (!ringq_is_empty(dtp->to_send)) { - struct du * pdu_ctrl; - pdu_ctrl = ringq_pop(dtp->to_send); - if (pdu_ctrl) { - dtp_pdu_send(dtp, dtp->rmt, pdu_ctrl); - } - } + + dtp_send_pending_ctrl_pdus(dtp); } else { pci = process_A_expiration(dtp, dtcp); if (pci) pci_release(pci); @@ -1205,6 +1200,20 @@ static bool window_is_closed(struct dtp * dtp, return retval; } +void dtp_send_pending_ctrl_pdus(struct dtp * dtp) +{ + struct du * du_ctrl; + + while (!ringq_is_empty(dtp->to_send)) { + du_ctrl = ringq_pop(dtp->to_send); + if (du_ctrl && dtp_pdu_send(dtp, dtp->rmt, du_ctrl)) { + LOG_ERR("Problems sending DTCP Ctrl PDU"); + du_destroy(du_ctrl); + } + } +} +EXPORT_SYMBOL(dtp_send_pending_ctrl_pdus); + int dtp_write(struct dtp * instance, struct du * du) { @@ -1312,7 +1321,7 @@ int dtp_write(struct dtp * instance, /* Start rendezvous timer, wait for Tr to fire */ start_rv_timer = true; - rv = instance->sv->tr; + rv = jiffies_to_msecs(instance->sv->tr); } spin_unlock_bh(&instance->sv_lock); @@ -1518,12 +1527,8 @@ int dtp_receive(struct dtp * instance, return -1; } } - while (!ringq_is_empty(instance->to_send)) { - struct du * du_ctrl = ringq_pop(instance->to_send); - if (du_ctrl) { - dtp_pdu_send(instance, instance->rmt, du_ctrl); - } - } + + dtp_send_pending_ctrl_pdus(instance); pdu_post(instance, du); stats_inc_bytes(rx, instance->sv, sbytes); LOG_DBG("Data run flag DRF"); @@ -1599,13 +1604,7 @@ int dtp_receive(struct dtp * instance, LOG_ERR("Failed to update dtcp sv"); goto fail; } - while (!ringq_is_empty(instance->to_send)) { - struct du * du_ctrl; - du_ctrl = ringq_pop(instance->to_send); - if (du_ctrl) { - dtp_pdu_send(instance, instance->rmt, du_ctrl); - } - } + dtp_send_pending_ctrl_pdus(instance); if (!set_lft_win_edge) { du_destroy(du); return 0; @@ -1652,12 +1651,7 @@ int dtp_receive(struct dtp * instance, } } - while (!ringq_is_empty(instance->to_send)) { - struct du * du_ctrl = ringq_pop(instance->to_send); - if (du_ctrl) { - dtp_pdu_send(instance, instance->rmt, du_ctrl); - } - } + dtp_send_pending_ctrl_pdus(instance); if (list_empty(&instance->seqq->queue->head)) rtimer_stop(instance->timers.a); diff --git a/kernel/dtp.h b/kernel/dtp.h index 8275b8d637..82a75c5ea1 100644 --- a/kernel/dtp.h +++ b/kernel/dtp.h @@ -51,6 +51,8 @@ int dtp_sv_init(struct dtp * dtp, int dtp_write(struct dtp * instance, struct du * du); +void dtp_send_pending_ctrl_pdus(struct dtp * dtp); + /* DTP receives a PDU from RMT */ int dtp_receive(struct dtp * instance, struct du * du); From 305e2bedbf8aa91cffcfd97bfd91a1cf61d7ba69 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 26 Sep 2018 17:09:52 +0200 Subject: [PATCH 06/40] kernel: dtcp: Fix bug --- configure | 4 +++- kernel/dtcp.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 562380b203..f79c43995b 100755 --- a/configure +++ b/configure @@ -5,7 +5,9 @@ SRCDIR=`pwd` FLAGS="--enable-debug" TCP_UDP_BUFFER_SIZE=1500 INSTALL_PREFIX="/" -KERNBUILDDIR="/lib/modules/`uname -r`/build" +# KERNBUILDDIR="/lib/modules/`uname -r`/build" +KERNBUILDDIR="/lib/modules/4.4.0-43-Microsoft/build" + BUILD_USER="y" # Option parsing diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 5f4b060f5a..3695f515e3 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -457,7 +457,7 @@ static int update_window_and_rate(struct dtcp * dtcp, spin_unlock_bh(&dtcp->parent->sv_lock); if (cancel_rv_timer) - rtimer_stop(dtcp->parent->timers.rendezvous); + rtimer_stop(&dtcp->parent->timers.rendezvous); push_pdus_rmt(dtcp); From bc17dff290838f9d627443a953fbcaf5b00a44d7 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 26 Sep 2018 17:20:36 +0200 Subject: [PATCH 07/40] Fix configure --- configure | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure b/configure index f79c43995b..549fe33c86 100755 --- a/configure +++ b/configure @@ -5,8 +5,7 @@ SRCDIR=`pwd` FLAGS="--enable-debug" TCP_UDP_BUFFER_SIZE=1500 INSTALL_PREFIX="/" -# KERNBUILDDIR="/lib/modules/`uname -r`/build" -KERNBUILDDIR="/lib/modules/4.4.0-43-Microsoft/build" +KERNBUILDDIR="/lib/modules/`uname -r`/build" BUILD_USER="y" From 9f7f339925aab54c34d8ba72a6cbce91e0999777 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 27 Sep 2018 18:31:09 +0200 Subject: [PATCH 08/40] kernel: dtcp: Fix rendezvous and add logs --- kernel/dtcp-ps-default.c | 15 +++++++-------- kernel/dtp.c | 5 ++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 64533b0d70..f294de639e 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -311,7 +311,7 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) if (!dtcp) return -1; - LOG_INFO("Receiver rendezvous..."); + //LOG_INFO("Receiver rendezvous..."); spin_lock_bh(&dtcp->parent->sv_lock); /* TODO: check if retransmission control enabled */ @@ -332,13 +332,12 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) if (dtcp->sv->snd_rt_wind_edge != rcv_rt) { /* TODO what to do? */ } - - if (dtcp->parent->sv->rcv_left_window_edge != snd_lft) { - LOG_INFO("Credit difference is %d", - snd_lft - dtcp->parent->sv->rcv_left_window_edge); - dtcp->parent->sv->rcv_left_window_edge = snd_lft; - dtcp->sv->rcvr_rt_wind_edge = snd_lft + dtcp->sv->rcvr_credit; - } + LOG_INFO("RCVR rendezvous. RCV LWE: %d | RCV RWE: %d || SND LWE: %d | SND RWE: %d", + dtcp->parent->sv->rcv_left_window_edge, dtcp->sv->rcvr_rt_wind_edge, + snd_lft, snd_rt); + if (dtcp->sv->rcvr_credit > 0) { + dtcp->sv->rcvr_rt_wind_edge = snd_rt + dtcp->sv->rcvr_credit; + } } if (dtcp->sv->flow_ctl && dtcp->parent->sv->rate_based) { diff --git a/kernel/dtp.c b/kernel/dtp.c index 6a78d08de1..d69cc9d36b 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -72,7 +72,7 @@ static struct dtp_sv default_sv = { .MPL = 1000, .R = 100, .A = 0, - .tr = 0, + .tr = 100, .rcv_left_window_edge = 0, .window_closed = false, .drf_flag = true, @@ -1351,6 +1351,9 @@ int dtp_write(struct dtp * instance, spin_unlock_bh(&instance->sv_lock); if (start_rv_timer) { + LOG_INFO("Window is closed. SND LWE: %d | SND RWE: %d", + instance->dtcp->sv->snd_lft_win, + instance->dtcp->sv->snd_rt_wind_edge); /* Send rendezvous PDU and start time */ rtimer_start(&instance->timers.rendezvous, rv); } From daea3002a1bf6c00fe3ac26cd0fc3cead41d5798 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Mon, 1 Oct 2018 18:43:22 +0200 Subject: [PATCH 09/40] kernel: dtcp: Fix rendezvous and add logs --- kernel/dtcp-ps-default.c | 5 ++--- kernel/dtp.c | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index f294de639e..49c75879ff 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -335,9 +335,8 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) LOG_INFO("RCVR rendezvous. RCV LWE: %d | RCV RWE: %d || SND LWE: %d | SND RWE: %d", dtcp->parent->sv->rcv_left_window_edge, dtcp->sv->rcvr_rt_wind_edge, snd_lft, snd_rt); - if (dtcp->sv->rcvr_credit > 0) { - dtcp->sv->rcvr_rt_wind_edge = snd_rt + dtcp->sv->rcvr_credit; - } + + dtcp->sv->rcvr_rt_wind_edge = snd_lft + dtcp->sv->rcvr_credit; } if (dtcp->sv->flow_ctl && dtcp->parent->sv->rate_based) { diff --git a/kernel/dtp.c b/kernel/dtp.c index d69cc9d36b..8ad46fe67c 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1351,9 +1351,10 @@ int dtp_write(struct dtp * instance, spin_unlock_bh(&instance->sv_lock); if (start_rv_timer) { - LOG_INFO("Window is closed. SND LWE: %d | SND RWE: %d", + LOG_INFO("Window is closed. SND LWE: %d | SND RWE: %d | TR: %d", instance->dtcp->sv->snd_lft_win, - instance->dtcp->sv->snd_rt_wind_edge); + instance->dtcp->sv->snd_rt_wind_edge, + instance->sv->tr); /* Send rendezvous PDU and start time */ rtimer_start(&instance->timers.rendezvous, rv); } From 9ba37755b2f9707f5f6cad362b3ef38f454f6a64 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Tue, 2 Oct 2018 14:26:51 +0200 Subject: [PATCH 10/40] kernel: dtcp: Fix rendezvous and add logs --- kernel/dtp-ps-default.c | 3 +++ kernel/dtp.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/dtp-ps-default.c b/kernel/dtp-ps-default.c index c112b9f844..2a96c4d4e7 100644 --- a/kernel/dtp-ps-default.c +++ b/kernel/dtp-ps-default.c @@ -41,6 +41,7 @@ int default_transmission_control(struct dtp_ps * ps, struct du * du) { struct dtp * dtp; + struct dtcp * dtcp; dtp = ps->dm; if (!dtp) { @@ -48,12 +49,14 @@ int default_transmission_control(struct dtp_ps * ps, struct du * du) du_destroy(du); return -1; } + dtcp = dtp->dtcp; /* Post SDU to RMT */ LOG_DBG("defaultTxPolicy - sending to rmt"); spin_lock_bh(&dtp->sv_lock); dtp->sv->max_seq_nr_sent = pci_sequence_number_get(&du->pci); + dtcp->sv->snd_lft_win = pci_sequence_number_get(&du->pci); spin_unlock_bh(&dtp->sv_lock); LOG_DBG("local_soft_irq_pending: %d", local_softirq_pending()); diff --git a/kernel/dtp.c b/kernel/dtp.c index 8ad46fe67c..d20d9df5c4 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1356,7 +1356,7 @@ int dtp_write(struct dtp * instance, instance->dtcp->sv->snd_rt_wind_edge, instance->sv->tr); /* Send rendezvous PDU and start time */ - rtimer_start(&instance->timers.rendezvous, rv); + rtimer_start(&instance->timers.rendezvous, rv + 10); } return 0; From f0dd803b0ce5fca10c0b12e4ad4b8f3ad1e438e0 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Tue, 2 Oct 2018 17:32:50 +0200 Subject: [PATCH 11/40] kernel: dtcp: Fix rendezvous and add logs --- kernel/dtp-ps-default.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/dtp-ps-default.c b/kernel/dtp-ps-default.c index 2a96c4d4e7..aeb75949e3 100644 --- a/kernel/dtp-ps-default.c +++ b/kernel/dtp-ps-default.c @@ -56,7 +56,8 @@ int default_transmission_control(struct dtp_ps * ps, struct du * du) spin_lock_bh(&dtp->sv_lock); dtp->sv->max_seq_nr_sent = pci_sequence_number_get(&du->pci); - dtcp->sv->snd_lft_win = pci_sequence_number_get(&du->pci); + dtcp->sv->snd_lft_win = dtp->sv->max_seq_nr_sent; + LOG_INFO("Default TX, SND LWE: %d", dtcp->sv->snd_lft_win); spin_unlock_bh(&dtp->sv_lock); LOG_DBG("local_soft_irq_pending: %d", local_softirq_pending()); From dc5ce1839c831e07f60f16f2a34966c8f4c53390 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 3 Oct 2018 15:06:23 +0200 Subject: [PATCH 12/40] kernel: dtcp: Fix rendezvous and add logs --- kernel/dtp-utils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index 99d45a3f23..ca8498d90d 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -300,6 +300,7 @@ void cwq_deliver(struct cwq * queue, } } dtp->sv->max_seq_nr_sent = pci_sequence_number_get(&du->pci); + dtcp->sv->snd_lft_win = dtp->sv->max_seq_nr_sent; dtp_pdu_send(dtp, rmt, du); } From 25fadb7faa8a01017e311dffb3f869f0d6e40273 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 3 Oct 2018 15:28:26 +0200 Subject: [PATCH 13/40] kernel: dtcp: Fix rendezvous and add logs --- kernel/dtp-ps-default.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/dtp-ps-default.c b/kernel/dtp-ps-default.c index aeb75949e3..0dc8dfa8a9 100644 --- a/kernel/dtp-ps-default.c +++ b/kernel/dtp-ps-default.c @@ -57,7 +57,6 @@ int default_transmission_control(struct dtp_ps * ps, struct du * du) spin_lock_bh(&dtp->sv_lock); dtp->sv->max_seq_nr_sent = pci_sequence_number_get(&du->pci); dtcp->sv->snd_lft_win = dtp->sv->max_seq_nr_sent; - LOG_INFO("Default TX, SND LWE: %d", dtcp->sv->snd_lft_win); spin_unlock_bh(&dtp->sv_lock); LOG_DBG("local_soft_irq_pending: %d", local_softirq_pending()); From e2103ac6d6cba18b81636daed8e3294ecb54eae7 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Fri, 5 Oct 2018 17:39:45 +0200 Subject: [PATCH 14/40] kernel: dtcp: Fix rendezvous, add reliable ack mechanism --- kernel/dtcp-ps-default.c | 12 ++++- kernel/dtcp.c | 109 +++++++++++++++++++++++++++------------ kernel/dtp.c | 11 ++-- kernel/efcp-str.h | 19 +++---- 4 files changed, 105 insertions(+), 46 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 49c75879ff..82408d72c3 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -34,6 +34,7 @@ #include "dtp-utils.h" #include "du.h" #include "logs.h" +#include "rds/rtimer.h" int default_lost_control_pdu(struct dtcp_ps * ps) { @@ -304,6 +305,7 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) struct dtcp * dtcp; struct du * du; seq_num_t rcv_lft, rcv_rt, snd_lft, snd_rt; + timeout_t rv; if (!ps) return -1; @@ -311,8 +313,6 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) if (!dtcp) return -1; - //LOG_INFO("Receiver rendezvous..."); - spin_lock_bh(&dtcp->parent->sv_lock); /* TODO: check if retransmission control enabled */ @@ -337,6 +337,8 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) snd_lft, snd_rt); dtcp->sv->rcvr_rt_wind_edge = snd_lft + dtcp->sv->rcvr_credit; + //this would be enough as a normal ACK to the RV packet, however, we need something specific for the reliable ACK + //that is, a timer :( } if (dtcp->sv->flow_ctl && dtcp->parent->sv->rate_based) { @@ -347,12 +349,18 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) * expected to have DRF bit set to true */ + dtcp->sv->rendezvous_rcvr = true; + spin_unlock_bh(&dtcp->parent->sv_lock); /* Send a ControlAck PDU to confirm reception of RendezvousPDU via * lastControlPDU value or send any other control PDU with Flow Control * information opening the window. */ + if (dtcp->sv->rcvr_credit != 0) { + rv = jiffies_to_msecs(dtcp->parent->sv->tr); + rtimer_start(&dtcp->rendezvous_rcv, rv); + } du = pdu_ctrl_generate(dtcp, PDU_TYPE_FC); if (!du) return -1; diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 3695f515e3..3517a35dbc 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -171,6 +171,81 @@ RINA_SYSFS_OPS(dtcp); RINA_ATTRS(dtcp, rtt, srtt, rttvar, ps_name); RINA_KTYPE(dtcp); +static int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) +{ + struct du * du; + + du = pdu_ctrl_generate(dtcp, type); + if (!du) { + atomic_dec(&dtcp->cpdus_in_transit); + return -1; + } + + if (direct) { + if (dtp_pdu_send(dtcp->parent, dtcp->rmt, du)){ + atomic_dec(&dtcp->cpdus_in_transit); + du_destroy(du); + return -1; + } + } else { + if (dtcp_pdu_send(dtcp, du)){ + atomic_dec(&dtcp->cpdus_in_transit); + du_destroy(du); + return -1; + } + } + + dump_we(dtcp, &du->pci); + + atomic_dec(&dtcp->cpdus_in_transit); + + return 0; +} + +/* Runs the Rendezvous-at-receiver timer */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) +static void tf_rendezvous_rcv(void * data) +#else +static void tf_rendezvous_rcv(struct timer_list * tl) +#endif +{ + struct dtcp * dtcp; + struct dtp * dtp; + bool start_rv_rcv_timer; + timeout_t rv; + + LOG_INFO("Running rendezvous-at-receiver timer..."); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) + dtcp = (struct dtcp *) data; +#else + dtcp = from_timer(dtcp, tl, rendezvous_rcv); +#endif + if (!dtcp) { + LOG_ERR("No dtcp to work with"); + return; + } + dtp = dtcp->parent; + + /* Check if the reliable ACK PDU needs to be sent*/ + start_rv_rcv_timer = false; + spin_lock_bh(&dtp->sv_lock); + if (dtcp->sv->rendezvous_rcvr) { + /* Start rendezvous-at-receiver timer, wait for Tr to fire */ + start_rv_rcv_timer = true; + rv = jiffies_to_msecs(dtp->sv->tr); + } + spin_unlock_bh(&dtp->sv_lock); + + if (start_rv_rcv_timer) { + LOG_INFO("DTCP Sending FC (CPU: %d)", smp_processor_id()); + /* Send rendezvous PDU and start timer */ + ctrl_pdu_send(dtcp, PDU_TYPE_FC, true); + rtimer_start(&dtcp->rendezvous_rcv, rv); + } + + return; +} + static int push_pdus_rmt(struct dtcp * dtcp) { ASSERT(dtcp); @@ -705,37 +780,6 @@ pdu_type_t pdu_ctrl_type_get(struct dtcp * dtcp, seq_num_t seq) } EXPORT_SYMBOL(pdu_ctrl_type_get); -static int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) -{ - struct du * du; - - du = pdu_ctrl_generate(dtcp, type); - if (!du) { - atomic_dec(&dtcp->cpdus_in_transit); - return -1; - } - - if (direct) { - if (dtp_pdu_send(dtcp->parent, dtcp->rmt, du)){ - atomic_dec(&dtcp->cpdus_in_transit); - du_destroy(du); - return -1; - } - } else { - if (dtcp_pdu_send(dtcp, du)){ - atomic_dec(&dtcp->cpdus_in_transit); - du_destroy(du); - return -1; - } - } - - dump_we(dtcp, &du->pci); - - atomic_dec(&dtcp->cpdus_in_transit); - - return 0; -} - int dtcp_ack_flow_control_pdu_send(struct dtcp * dtcp, seq_num_t seq) { pdu_type_t type; @@ -1069,7 +1113,7 @@ EXPORT_SYMBOL(dtcp_set_policy_set_param); struct dtcp * dtcp_create(struct dtp * dtp, struct rmt * rmt, struct dtcp_config * dtcp_cfg, - struct robject * parent) + struct robject * parent) { struct dtcp * tmp; string_t * ps_name; @@ -1114,6 +1158,7 @@ struct dtcp * dtcp_create(struct dtp * dtp, tmp->cfg = dtcp_cfg; tmp->rmt = rmt; atomic_set(&tmp->cpdus_in_transit, 0); + rtimer_init(tf_rendezvous_rcv, &tmp->rendezvous_rcv, tmp); rina_component_init(&tmp->base); diff --git a/kernel/dtp.c b/kernel/dtp.c index d20d9df5c4..81eaafb762 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1068,7 +1068,7 @@ struct dtp * dtp_create(struct efcp * efcp, rtimer_init(tf_receiver_inactivity, &dtp->timers.receiver_inactivity, dtp); rtimer_init(tf_a, &dtp->timers.a, dtp); rtimer_init(tf_rate_window, &dtp->timers.rate_window, dtp); - rtimer_init(tf_rendezvous, &dtp->timers.rendezvous, dtp); + rtimer_init(tf_rendezvous, &dtp->timers.rendezvous, dtp); dtp->to_post = ringq_create(TO_POST_LENGTH); if (!dtp->to_post) { @@ -1338,7 +1338,7 @@ int dtp_write(struct dtp * instance, } rcu_read_unlock(); - /* Check if rendezvous PDU needs to be send*/ + /* Check if rendezvous PDU needs to be sent*/ start_rv_timer = false; spin_lock_bh(&instance->sv_lock); if (!instance->dtcp->sv->rendezvous_sndr) { @@ -1509,7 +1509,7 @@ int dtp_receive(struct dtp * instance, LOG_DBG("DTP receive started..."); dtcp = instance->dtcp; - efcp = instance->efcp; + efcp = instance->efcp; spin_lock_bh(&instance->sv_lock); a = instance->sv->A; @@ -1607,6 +1607,11 @@ int dtp_receive(struct dtp * instance, return -1; } #endif + /* This is an acceptable data PDU, stop reliable ACK timer */ + if (dtcp->sv->rendezvous_rcvr) { + dtcp->sv->rendezvous_rcvr = false; + rtimer_stop(&dtcp->rendezvous_rcv); + } if (!a) { bool set_lft_win_edge; diff --git a/kernel/efcp-str.h b/kernel/efcp-str.h index fe3333399e..64e26849f2 100644 --- a/kernel/efcp-str.h +++ b/kernel/efcp-str.h @@ -153,7 +153,7 @@ struct dtp { * NOTE: The DTP State Vector is discarded only after and explicit * release by the AP or by the system (if the AP crashes). */ - struct dtp_sv * sv; /* The state-vector */ + struct dtp_sv * sv; /* The state-vector */ spinlock_t sv_lock; /* The state vector lock (DTP & DTCP) */ struct rina_component base; @@ -168,11 +168,11 @@ struct dtp { struct timer_list a; struct timer_list rate_window; struct timer_list rtx; - struct timer_list rendezvous; + struct timer_list rendezvous; } timers; - struct robject robj; + struct robject robj; - spinlock_t lock; + spinlock_t lock; }; /* This is the DT-SV part maintained by DTCP */ @@ -266,10 +266,10 @@ struct dtcp_sv { /* Rate based both in and out-bound */ - /* Last time-instant when the credit check has been done. - * This is used by rate-based flow control mechanism. - */ - struct timespec last_time; + /* Last time-instant when the credit check has been done. + * This is used by rate-based flow control mechanism. + */ + struct timespec last_time; /* * Control of duplicated control PDUs @@ -306,9 +306,10 @@ struct dtcp { struct rina_component base; struct dtcp_config * cfg; struct rmt * rmt; + struct timer_list rendezvous_rcv; atomic_t cpdus_in_transit; - struct robject robj; + struct robject robj; }; From a8d362f57250540ce85908440da157e4de39ea72 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Mon, 15 Oct 2018 10:10:45 +0200 Subject: [PATCH 15/40] Add mechanism to estimate RTT without RTX control --- kernel/dtcp-ps-default.c | 122 ++++++++++++++++-------- kernel/dtcp-ps-default.h | 2 + kernel/dtcp.c | 36 +++++-- kernel/dtp-utils.c | 201 +++++++++++++++++++++++++++++++++++++++ kernel/dtp-utils.h | 11 ++- kernel/dtp.c | 17 +++- kernel/efcp-str.h | 13 +++ kernel/efcp.c | 9 ++ 8 files changed, 361 insertions(+), 50 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 82408d72c3..32d37a2738 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -235,12 +235,65 @@ int default_rate_reduction(struct dtcp_ps * ps, const struct pci * pci) return 0; } +static int rtt_calculation(struct dtcp_ps * ps, timeout_t start_time) +{ + struct dtcp * dtcp; + uint_t rtt, new_sample, srtt, rttvar, trmsecs; + timeout_t a; + int abs; + + if (!ps) + return -1; + dtcp = ps->dm; + if (!dtcp) + return -1; + + new_sample = jiffies_to_msecs(jiffies - start_time); + + spin_lock_bh(&dtcp->parent->sv_lock); + + rtt = dtcp->sv->rtt; + srtt = dtcp->sv->srtt; + rttvar = dtcp->sv->rttvar; + a = dtcp->parent->sv->A; + + if (!rtt) { + rtt = new_sample; + rttvar = new_sample >> 1; + srtt = new_sample; + } else { + /* RTT <== RTT * (112/128) + SAMPLE * (16/128)*/ + rtt = (rtt * 112 + (new_sample << 4)) >> 7; + abs = srtt - new_sample; + abs = abs < 0 ? -abs : abs; + rttvar = ((3 * rttvar) >> 2) + (((uint_t)abs) >> 2); + } + + /*FIXME: k, G, alpha and betha should be parameters passed to the policy + * set. Probably moving them to ps->priv */ + + /* k * rttvar = 4 * rttvar */ + trmsecs = rttvar << 2; + /* G is 0.1s according to RFC6298, then 100ms */ + trmsecs = 100 > trmsecs ? 100 : trmsecs; + trmsecs += srtt + jiffies_to_msecs(a); + /* RTO (tr) less than 1s? (not for the common policy) */ + /*trmsecs = trmsecs < 1000 ? 1000 : trmsecs;*/ + + dtcp->sv->rtt = rtt; + dtcp->sv->rttvar = rttvar; + dtcp->sv->srtt = srtt; + dtcp->parent->sv->tr = msecs_to_jiffies(trmsecs); + + spin_unlock_bh(&dtcp->parent->sv_lock); + + return 0; +} + int default_rtt_estimator(struct dtcp_ps * ps, seq_num_t sn) { struct dtcp * dtcp; - uint_t rtt, new_sample, srtt, rttvar, trmsecs; - timeout_t start_time, a; - int abs; + timeout_t start_time; if (!ps) return -1; @@ -252,52 +305,37 @@ int default_rtt_estimator(struct dtcp_ps * ps, seq_num_t sn) start_time = rtxq_entry_timestamp(dtcp->parent->rtxq, sn); if (start_time == 0) { - LOG_DBG("RTTestimator: PDU %u has been retransmitted", sn); + LOG_DBG("RTTestimator: PDU %u has been retransmitted", sn); return 0; } - new_sample = jiffies_to_msecs(jiffies - start_time); - - spin_lock_bh(&dtcp->parent->sv_lock); + rtt_calculation(ps, start_time); - rtt = dtcp->sv->rtt; - srtt = dtcp->sv->srtt; - rttvar = dtcp->sv->rttvar; - a = dtcp->parent->sv->A; - - if (!rtt) { - rtt = new_sample; - rttvar = new_sample >> 1; - srtt = new_sample; - } else { - /* RTT <== RTT * (112/128) + SAMPLE * (16/128)*/ - rtt = (rtt * 112 + (new_sample << 4)) >> 7; - abs = srtt - new_sample; - abs = abs < 0 ? -abs : abs; - rttvar = ((3 * rttvar) >> 2) + (((uint_t)abs) >> 2); - } + return 0; +} - /*FIXME: k, G, alpha and betha should be parameters passed to the policy - * set. Probably moving them to ps->priv */ +int default_rtt_estimator_nortx(struct dtcp_ps * ps, seq_num_t sn) +{ + struct dtcp * dtcp; + timeout_t start_time; - /* k * rttvar = 4 * rttvar */ - trmsecs = rttvar << 2; - /* G is 0.1s according to RFC6298, then 100ms */ - trmsecs = 100 > trmsecs ? 100 : trmsecs; - trmsecs += srtt + jiffies_to_msecs(a); - /* RTO (tr) less than 1s? (not for the common policy) */ - /*trmsecs = trmsecs < 1000 ? 1000 : trmsecs;*/ + if (!ps) + return -1; + dtcp = ps->dm; + if (!dtcp) + return -1; - dtcp->sv->rtt = rtt; - dtcp->sv->rttvar = rttvar; - dtcp->sv->srtt = srtt; - dtcp->parent->sv->tr = msecs_to_jiffies(trmsecs); + LOG_DBG("RTT Estimator with only flow control..."); - spin_unlock_bh(&dtcp->parent->sv_lock); + start_time = rttq_entry_timestamp(dtcp->parent->rttq, sn); + if (start_time == 0) { + LOG_DBG("RTTestimator: PDU %u has been retransmitted", sn); + return 0; + } - LOG_DBG("New RTT %u; New Tr: %u ms", rtt, trmsecs); + rtt_calculation(ps, start_time); - return 0; + return 0; } int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) @@ -388,7 +426,11 @@ struct ps_base * dtcp_ps_default_create(struct rina_component * component) ps->priv = NULL; ps->flow_init = NULL; ps->lost_control_pdu = default_lost_control_pdu; - ps->rtt_estimator = default_rtt_estimator; + if (ps->rtx_ctrl) { + ps->rtt_estimator = default_rtt_estimator; + } else { + ps->rtt_estimator = default_rtt_estimator_nortx; + } ps->retransmission_timer_expiry = NULL; ps->received_retransmission = NULL; ps->sender_ack = default_sender_ack; diff --git a/kernel/dtcp-ps-default.h b/kernel/dtcp-ps-default.h index b1fc3213cd..804fb1f4cb 100644 --- a/kernel/dtcp-ps-default.h +++ b/kernel/dtcp-ps-default.h @@ -55,6 +55,8 @@ int default_rate_reduction(struct dtcp_ps * ps, const struct pci * pci); int default_rtt_estimator(struct dtcp_ps * ps, seq_num_t sn); +int default_rtt_estimator_nortx(struct dtcp_ps * ps, seq_num_t sn); + int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci); #endif /* RINA_DTCP_PS_COMMON_H */ diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 3517a35dbc..b175eaea6f 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -546,8 +546,27 @@ static int update_window_and_rate(struct dtcp * dtcp, static int rcv_flow_ctl(struct dtcp * dtcp, struct du * du) { - LOG_DBG("DTCP received FC (CPU: %d)", smp_processor_id()); - return update_window_and_rate(dtcp, du); + struct dtcp_ps * ps; + seq_num_t seq; + uint_t credit; + + credit = dtcp->sv->sndr_credit; + + seq = pci_control_new_rt_wind_edge(&du->pci); + + rcu_read_lock(); + ps = container_of(rcu_dereference(dtcp->base.ps), + struct dtcp_ps, base); + + LOG_DBG("DTCP received FC (CPU: %d)", smp_processor_id()); + if (!ps->rtx_ctrl && ps->rtt_estimator) + ps->rtt_estimator(ps, seq - credit); + + rcu_read_unlock(); + + rttq_drop(dtcp->parent->rttq, seq); + + return update_window_and_rate(dtcp, du); } static int rcv_ack_and_flow_ctl(struct dtcp * dtcp, @@ -562,8 +581,8 @@ static int rcv_ack_and_flow_ctl(struct dtcp * dtcp, ps = container_of(rcu_dereference(dtcp->base.ps), struct dtcp_ps, base); /* This updates sender LWE */ - if (ps->rtx_ctrl && ps->rtt_estimator) - ps->rtt_estimator(ps, pci_control_ack_seq_num(&du->pci)); + if (ps->rtx_ctrl && ps->rtt_estimator) + ps->rtt_estimator(ps, seq); if (ps->sender_ack(ps, seq)) LOG_ERR("Could not update RTXQ and LWE"); rcu_read_unlock(); @@ -996,7 +1015,11 @@ int dtcp_select_policy_set(struct dtcp * dtcp, ps->rate_reduction = default_rate_reduction; } if (!ps->rtt_estimator) { - ps->rtt_estimator = default_rtt_estimator; + if (ps->rtx_ctrl) { + ps->rtt_estimator = default_rtt_estimator; + } else { + ps->rtt_estimator = default_rtt_estimator_nortx; + } } if (!ps->rcvr_rendezvous) { ps->rcvr_rendezvous = default_rcvr_rendezvous; @@ -1218,8 +1241,9 @@ int dtcp_destroy(struct dtcp * instance) if (instance->sv) rkfree(instance->sv); if (instance->cfg) dtcp_config_destroy(instance->cfg); + rtimer_destroy(&instance->rendezvous_rcv); rina_component_fini(&instance->base); - robject_del(&instance->robj); + robject_del(&instance->robj); rkfree(instance); LOG_DBG("Instance %pK destroyed successfully", instance); diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index ca8498d90d..e3c6656a6e 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -970,3 +970,204 @@ int dtp_pdu_send(struct dtp * dtp, return 0; } EXPORT_SYMBOL(dtp_pdu_send); + +/* Here begins the RTT estimator when there is not RTX*/ + +static struct rtt_entry * rtt_entry_create_gfp(seq_num_t sn, gfp_t flag) +{ + struct rtt_entry * tmp; + + tmp = rkzalloc(sizeof(*tmp), flag); + if (!tmp) + return NULL; + + tmp->sn = sn; + tmp->time_stamp = jiffies; + + INIT_LIST_HEAD(&tmp->next); + + return tmp; +} + +static struct rtt_entry * rtt_entry_create(seq_num_t sn) +{ return rtt_entry_create_gfp(sn, GFP_ATOMIC); } + +int rtt_entry_destroy(struct rtt_entry * entry) +{ + if (!entry) + return -1; + + list_del(&entry->next); + rkfree(entry); + + return 0; +} +EXPORT_SYMBOL(rtt_entry_destroy); + +static struct rttq * rttq_create_gfp(gfp_t flags) +{ + struct rttq * tmp; + + tmp = rkzalloc(sizeof(*tmp), flags); + if (!tmp) + return NULL; + + INIT_LIST_HEAD(&tmp->head); + + return tmp; +} + +struct rttq * rttq_create(void) +{ return rttq_create_gfp(GFP_KERNEL); } + +static int rttq_entry_destroy(struct rtt_entry * entry) +{ + list_del(&entry->next); + rkfree(entry); + return 0; +} + +static int rttq_flush(struct rttq * q) +{ + struct rtt_entry * cur, * n; + + ASSERT(q); + + list_for_each_entry_safe(cur, n, &q->head, next) { + rttq_entry_destroy(cur); + } + + return 0; +} + +int rttq_destroy(struct rttq * q) +{ + unsigned long flags; + + if (!q) + return -1; + + spin_lock_irqsave(&q->lock, flags); + rttq_flush(q); + spin_unlock_irqrestore(&q->lock, flags); + + rkfree(q); + + return 0; +} + +unsigned long rttqueue_entry_timestamp(struct rttq * q, seq_num_t sn) +{ + struct rtt_entry * cur; + seq_num_t csn; + + list_for_each_entry(cur, &q->head, next) { + csn = cur->sn; + if (csn > sn) { + LOG_WARN("PDU not in RTTQ (duplicate ACK). Received " + "SN: %u, RTTQ SN: %u", sn, csn); + return 0; + } + if (csn == sn) { + return cur->time_stamp; + } + } + + return 0; +} + +unsigned long rttq_entry_timestamp(struct rttq * q, seq_num_t sn) +{ + unsigned long timestamp; + + if (!q) + return 0; + + spin_lock_bh(&q->lock); + timestamp = rttqueue_entry_timestamp(q, sn); + spin_unlock_bh(&q->lock); + + return timestamp; +} +EXPORT_SYMBOL(rttq_entry_timestamp); + +static int rttq_push_ni(struct rttq * q, seq_num_t sn) +{ + struct rtt_entry * new, * cur, * last = NULL; + seq_num_t psn; + + new = rtt_entry_create(sn); + if (!new) { + LOG_ERR("Could not create an rtt queue entry"); + + return -1; + } + + if (list_empty(&q->head)) { + list_add(&new->next, &q->head); + LOG_DBG("First PDU with seqnum: %u push to RTTq at: %pk", + sn, q); + return 0; + } + + last = list_last_entry(&q->head, struct rtt_entry, next); + if (!last) + return -1; + + psn = last->sn; + if (sn == psn) { + LOG_ERR("Another PDU with the same seq_num %u, is in " + "the RTT queue!", sn); + return 0; + } + if (sn > psn) { + list_add_tail(&new->next, &q->head); + LOG_DBG("Last PDU with seqnum: %u push to RTTq at: %pk", + sn, q); + return 0; + } + + list_for_each_entry(cur, &q->head, next) { + psn = cur->sn; + if (sn == psn) { + LOG_ERR("Another PDU with the same seq_num is in " + "the RTT queue!"); + return 0; + } + if (sn > psn) { + list_add(&new->next, &cur->next); + LOG_DBG("Middle PDU with seqnum: %u push to " + "rtxq at: %pk", sn, q); + return 0; + } + } + + LOG_DBG("SN not pushed!"); + + return 0; +} + +int rttq_push(struct rttq * q, seq_num_t sn) +{ + int to_return; + + spin_lock_bh(&q->lock); + to_return = rttq_push_ni(q, sn); + spin_unlock_bh(&q->lock); + + return to_return; +} + +int rttq_drop(struct rttq * q, seq_num_t sn) +{ + struct rtt_entry * cur, * n; + + list_for_each_entry_safe(cur, n, &q->head, next) { + if (cur->sn <= sn) { + LOG_DBG("Seq num removed: %u", cur->sn); + rtt_entry_destroy(cur); + } else + return 0; + } + return 0; +} diff --git a/kernel/dtp-utils.h b/kernel/dtp-utils.h index 9f1f09a9e8..8c418957e8 100644 --- a/kernel/dtp-utils.h +++ b/kernel/dtp-utils.h @@ -73,6 +73,13 @@ int rtxq_nack(struct rtxq * q, int rtxq_flush(struct rtxq * q); int dtp_pdu_send(struct dtp * dtp, - struct rmt * rmt, - struct du * du); + struct rmt * rmt, + struct du * du); + +struct rttq; + +struct rttq * rttq_create(void); +int rttq_destroy(struct rttq * q); +unsigned long rttq_entry_timestamp(struct rttq * q, seq_num_t sn); +int rttq_drop(struct rttq * q, seq_num_t sn); #endif diff --git a/kernel/dtp.c b/kernel/dtp.c index 81eaafb762..370734e353 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -72,7 +72,7 @@ static struct dtp_sv default_sv = { .MPL = 1000, .R = 100, .A = 0, - .tr = 100, + .tr = 0, .rcv_left_window_edge = 0, .window_closed = false, .drf_flag = true, @@ -1111,6 +1111,7 @@ int dtp_destroy(struct dtp * instance) struct dtcp * dtcp = NULL; struct cwq * cwq = NULL; struct rtxq * rtxq = NULL; + struct rttq * rttq = NULL; int ret = 0; if (!instance) @@ -1133,6 +1134,11 @@ int dtp_destroy(struct dtp * instance) instance->rtxq = NULL; /* Useful */ } + if (instance->rttq) { + rttq = instance->rttq; + instance->rttq = NULL; + } + spin_unlock_bh(&instance->lock); if (dtcp) { @@ -1156,6 +1162,13 @@ int dtp_destroy(struct dtp * instance) } } + if (rttq) { + if (rttq_destroy(rttq)) { + LOG_ERR("Failed to destroy rexmsn queue"); + ret = -1; + } + } + rtimer_destroy(&instance->timers.a); /* tf_a posts workers that restart sender_inactivity timer, so the wq * must be flushed before destroying the timer */ @@ -1164,7 +1177,7 @@ int dtp_destroy(struct dtp * instance) rtimer_destroy(&instance->timers.receiver_inactivity); rtimer_destroy(&instance->timers.rate_window); rtimer_destroy(&instance->timers.rtx); - rtimer_destroy(&instance->timers.rendezvous); + rtimer_destroy(&instance->timers.rendezvous); if (instance->to_post) ringq_destroy(instance->to_post, (void (*)(void *)) du_destroy); diff --git a/kernel/efcp-str.h b/kernel/efcp-str.h index 64e26849f2..c81a5b2fb1 100644 --- a/kernel/efcp-str.h +++ b/kernel/efcp-str.h @@ -109,6 +109,18 @@ struct rtxq { struct rtxqueue * queue; }; +struct rtt_entry { + unsigned long time_stamp; + seq_num_t sn; + struct list_head next; +}; + +struct rttq { + spinlock_t lock; + struct dtp * parent; + struct list_head head; +}; + /* This is the DT-SV part maintained by DTP */ struct dtp_sv { uint_t max_flow_pdu_size; @@ -148,6 +160,7 @@ struct dtp { struct cwq * cwq; struct rtxq * rtxq; + struct rttq * rttq; /* * NOTE: The DTP State Vector is discarded only after and explicit diff --git a/kernel/efcp.c b/kernel/efcp.c index 1f66146f85..be1350ce1f 100644 --- a/kernel/efcp.c +++ b/kernel/efcp.c @@ -502,6 +502,7 @@ cep_id_t efcp_connection_create(struct efcp_container * container, timeout_t mpl, a, r = 0, tr = 0; struct dtp_ps * dtp_ps; bool dtcp_present; + struct rttq * rttq; if (!container) { LOG_ERR("Bogus container passed, bailing out"); @@ -604,6 +605,14 @@ cep_id_t efcp_connection_create(struct efcp_container * container, return cep_id_bad(); } efcp->dtp->rtxq = rtxq; + } else { + rttq = rttq_create(); + if (!rttq) { + LOG_ERR("Failed to create RTT queue"); + efcp_destroy(efcp); + return cep_id_bad(); + } + efcp->dtp->rttq = rttq; } efcp->dtp->efcp = efcp; From a9a547f5ff7cc7c9d22e8a9b806a4f2552db9b9b Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 17 Oct 2018 12:17:10 +0200 Subject: [PATCH 16/40] Remove some debug logs --- kernel/dtcp-ps-default.c | 2 +- kernel/dtp.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 32d37a2738..a57a91de1b 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -370,7 +370,7 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) if (dtcp->sv->snd_rt_wind_edge != rcv_rt) { /* TODO what to do? */ } - LOG_INFO("RCVR rendezvous. RCV LWE: %d | RCV RWE: %d || SND LWE: %d | SND RWE: %d", + LOG_DBG("RCVR rendezvous. RCV LWE: %d | RCV RWE: %d || SND LWE: %d | SND RWE: %d", dtcp->parent->sv->rcv_left_window_edge, dtcp->sv->rcvr_rt_wind_edge, snd_lft, snd_rt); diff --git a/kernel/dtp.c b/kernel/dtp.c index 370734e353..de2af83090 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -504,7 +504,7 @@ static void tf_rendezvous(struct timer_list * tl) bool start_rv_timer; timeout_t rv; - LOG_INFO("Running rendezvous timer..."); + LOG_DBG("Running rendezvous timer..."); #if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) dtp = (struct dtp *) data; #else @@ -1321,8 +1321,8 @@ int dtp_write(struct dtp * instance, } sn = dtcp->sv->snd_lft_win; - if (instance->sv->drf_flag || (sn == (csn - 1)) || - ! instance->sv->rexmsn_ctrl) { + if (instance->sv->drf_flag || + ((sn == (csn - 1)) && instance->sv->rexmsn_ctrl)) { pdu_flags_t pci_flags; pci_flags = pci_flags_get(&du->pci); pci_flags |= PDU_FLAGS_DATA_RUN; From 1453533fdedc1fdd39d6f39fe833dde1779d9dbd Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 17 Oct 2018 13:05:30 +0200 Subject: [PATCH 17/40] Add debug logs --- kernel/dtcp.c | 4 +++- kernel/dtp-utils.c | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index b175eaea6f..11a2ebb0ab 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -559,12 +559,14 @@ static int rcv_flow_ctl(struct dtcp * dtcp, struct dtcp_ps, base); LOG_DBG("DTCP received FC (CPU: %d)", smp_processor_id()); + LOG_INFO("New RWE: %u, Credit: %u, Seq Num RTT: %u", seq, credit, seq-credit); if (!ps->rtx_ctrl && ps->rtt_estimator) ps->rtt_estimator(ps, seq - credit); rcu_read_unlock(); - rttq_drop(dtcp->parent->rttq, seq); + rttq_drop(dtcp->parent->rttq, seq-credit); + LOG_INFO("New RTT estimation: %u", dtcp->parent->sv->tr); return update_window_and_rate(dtcp, du); } diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index e3c6656a6e..648c0eeeb9 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -1162,9 +1162,16 @@ int rttq_drop(struct rttq * q, seq_num_t sn) { struct rtt_entry * cur, * n; + if (list_empty(&q->head)) { + LOG_INFO("RTTQ empty"); + return 0; + } + cur = list_last_entry(&q->head, struct rtt_entry, next); + LOG_INFO("LAST ENTRY seq num: %u", cur->sn); + cur = NULL; list_for_each_entry_safe(cur, n, &q->head, next) { if (cur->sn <= sn) { - LOG_DBG("Seq num removed: %u", cur->sn); + LOG_INFO("Seq num removed: %u", cur->sn); rtt_entry_destroy(cur); } else return 0; From d5e5d12a496e3e53843babacada475aa7c5794d4 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 18 Oct 2018 19:53:03 +0200 Subject: [PATCH 18/40] Add missing mechanisms for RTT estimator --- kernel/dtp-utils.c | 1 + kernel/dtp-utils.h | 1 + kernel/dtp.c | 16 ++++++++++------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index 648c0eeeb9..d0b3fce193 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -1157,6 +1157,7 @@ int rttq_push(struct rttq * q, seq_num_t sn) return to_return; } +EXPORT_SYMBOL(rttq_push); int rttq_drop(struct rttq * q, seq_num_t sn) { diff --git a/kernel/dtp-utils.h b/kernel/dtp-utils.h index 8c418957e8..b93102e620 100644 --- a/kernel/dtp-utils.h +++ b/kernel/dtp-utils.h @@ -82,4 +82,5 @@ struct rttq * rttq_create(void); int rttq_destroy(struct rttq * q); unsigned long rttq_entry_timestamp(struct rttq * q, seq_num_t sn); int rttq_drop(struct rttq * q, seq_num_t sn); +int rttq_push(struct rttq * q, seq_num_t sn); #endif diff --git a/kernel/dtp.c b/kernel/dtp.c index 967bd3c9c6..1cfa115a0c 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1369,7 +1369,7 @@ int dtp_write(struct dtp * instance, instance->dtcp->sv->snd_rt_wind_edge, instance->sv->tr); /* Send rendezvous PDU and start time */ - rtimer_start(&instance->timers.rendezvous, rv + 10); + rtimer_start(&instance->timers.rendezvous, rv); } return 0; @@ -1395,30 +1395,34 @@ int dtp_write(struct dtp * instance, if (!cdu) { LOG_ERR("Failed to copy PDU"); LOG_ERR("PDU type: %d", pci_type(&du->pci)); - goto pdu_stats_err_exit; + goto pdu_stats_err_exit; } if (rtxq_push_ni(rtxq, cdu)) { LOG_ERR("Couldn't push to rtxq"); - goto pdu_stats_err_exit; + goto pdu_stats_err_exit; } + } else { + if (rttq_push(instance->rttq, csn)) { + LOG_ERR("Failed to push SN"); + } } if (ps->transmission_control(ps, du)) { LOG_ERR("Problems with transmission control"); - goto stats_err_exit; + goto stats_err_exit; } rcu_read_unlock(); spin_lock_bh(&instance->sv_lock); stats_inc_bytes(tx, instance->sv, sbytes); - spin_unlock_bh(&instance->sv_lock); + spin_unlock_bh(&instance->sv_lock); #if DTP_INACTIVITY_TIMERS_ENABLE /* Start SenderInactivityTimer */ if (rtimer_restart(&instance->timers.sender_inactivity, 3 * (mpl + r + a ))) { LOG_ERR("Failed to start sender_inactiviy timer"); - goto stats_nounlock_err_exit; + goto stats_nounlock_err_exit; return -1; } #endif From 28eb28cd0a5933d25a5352404bd731cf457876cd Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 25 Oct 2018 11:19:08 +0200 Subject: [PATCH 19/40] Add clean up of RTTQ and some missing locks --- kernel/dtp-ps-default.c | 3 +++ kernel/dtp-utils.c | 26 +++++++++++++++++--------- kernel/dtp-utils.h | 1 + kernel/dtp.c | 2 ++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/kernel/dtp-ps-default.c b/kernel/dtp-ps-default.c index 0dc8dfa8a9..1fa9aa6f30 100644 --- a/kernel/dtp-ps-default.c +++ b/kernel/dtp-ps-default.c @@ -173,6 +173,7 @@ int default_receiver_inactivity_timer(struct dtp_ps * ps) dtcp->sv->rcvr_rt_wind_edge = 0; dtp->sv->rcv_left_window_edge = 0; dtp_squeue_flush(dtp); + dtcp->sv->rendezvous_rcvr = false; dtp->sv->drf_required = true; spin_unlock_bh(&dtp->sv_lock); @@ -211,6 +212,8 @@ int default_sender_inactivity_timer(struct dtp_ps * ps) snd_rt_win = dtcp->sv->snd_rt_wind_edge; next_send = dtp->sv->seq_nr_to_send; dtcp->sv->snd_rt_wind_edge = next_send + init_credit; + dtcp->sv->rendezvous_sndr = false; + rttq_flush(dtp->rttq); LOG_DBG("Current values:\n\tinit_credit: %u " "max_sent: %u snd_rt_win: %u next_send: %u", diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index d0b3fce193..316e6924cb 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -992,7 +992,7 @@ static struct rtt_entry * rtt_entry_create_gfp(seq_num_t sn, gfp_t flag) static struct rtt_entry * rtt_entry_create(seq_num_t sn) { return rtt_entry_create_gfp(sn, GFP_ATOMIC); } -int rtt_entry_destroy(struct rtt_entry * entry) +static int rtt_entry_destroy(struct rtt_entry * entry) { if (!entry) return -1; @@ -1002,7 +1002,6 @@ int rtt_entry_destroy(struct rtt_entry * entry) return 0; } -EXPORT_SYMBOL(rtt_entry_destroy); static struct rttq * rttq_create_gfp(gfp_t flags) { @@ -1019,6 +1018,7 @@ static struct rttq * rttq_create_gfp(gfp_t flags) struct rttq * rttq_create(void) { return rttq_create_gfp(GFP_KERNEL); } +EXPORT_SYMBOL(rttq_create); static int rttq_entry_destroy(struct rtt_entry * entry) { @@ -1027,7 +1027,8 @@ static int rttq_entry_destroy(struct rtt_entry * entry) return 0; } -static int rttq_flush(struct rttq * q) +/* No locking required, it's always called with DTP-SV lock taken */ +int rttq_flush(struct rttq * q) { struct rtt_entry * cur, * n; @@ -1039,24 +1040,25 @@ static int rttq_flush(struct rttq * q) return 0; } +EXPORT_SYMBOL(rttq_flush); int rttq_destroy(struct rttq * q) { - unsigned long flags; if (!q) return -1; - spin_lock_irqsave(&q->lock, flags); + spin_lock(&q->lock); rttq_flush(q); - spin_unlock_irqrestore(&q->lock, flags); + spin_unlock(&q->lock); rkfree(q); return 0; } +EXPORT_SYMBOL(rttq_destroy); -unsigned long rttqueue_entry_timestamp(struct rttq * q, seq_num_t sn) +static unsigned long rttqueue_entry_timestamp(struct rttq * q, seq_num_t sn) { struct rtt_entry * cur; seq_num_t csn; @@ -1163,8 +1165,10 @@ int rttq_drop(struct rttq * q, seq_num_t sn) { struct rtt_entry * cur, * n; + spin_lock_bh(&q->lock); if (list_empty(&q->head)) { LOG_INFO("RTTQ empty"); + spin_unlock_bh(&q->lock); return 0; } cur = list_last_entry(&q->head, struct rtt_entry, next); @@ -1174,8 +1178,12 @@ int rttq_drop(struct rttq * q, seq_num_t sn) if (cur->sn <= sn) { LOG_INFO("Seq num removed: %u", cur->sn); rtt_entry_destroy(cur); - } else + } else { + spin_unlock_bh(&q->lock); return 0; - } + } + } + spin_unlock_bh(&q->lock); return 0; } +EXPORT_SYMBOL(rttq_drop); diff --git a/kernel/dtp-utils.h b/kernel/dtp-utils.h index b93102e620..c207758c5b 100644 --- a/kernel/dtp-utils.h +++ b/kernel/dtp-utils.h @@ -83,4 +83,5 @@ int rttq_destroy(struct rttq * q); unsigned long rttq_entry_timestamp(struct rttq * q, seq_num_t sn); int rttq_drop(struct rttq * q, seq_num_t sn); int rttq_push(struct rttq * q, seq_num_t sn); +int rttq_flush(struct rttq * q); #endif diff --git a/kernel/dtp.c b/kernel/dtp.c index 1cfa115a0c..14181b6b91 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1566,6 +1566,7 @@ int dtp_receive(struct dtp * instance, instance->sv->drf_required = false; instance->sv->rcv_left_window_edge = seq_num; dtp_squeue_flush(instance); + rttq_flush(instance->rttq); spin_unlock_bh(&instance->sv_lock); if (dtcp) { if (dtcp_sv_update(dtcp, &du->pci)) { @@ -1628,6 +1629,7 @@ int dtp_receive(struct dtp * instance, #endif /* This is an acceptable data PDU, stop reliable ACK timer */ if (dtcp->sv->rendezvous_rcvr) { + LOG_INFO("RV at receiver put to false"); dtcp->sv->rendezvous_rcvr = false; rtimer_stop(&dtcp->rendezvous_rcv); } From 21ed17aac0bb4f954cf67af4e16d0723efeee506 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 25 Oct 2018 11:47:13 +0200 Subject: [PATCH 20/40] Fix DRF init --- kernel/dtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dtp.c b/kernel/dtp.c index 14181b6b91..66b35b7afc 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -75,7 +75,7 @@ static struct dtp_sv default_sv = { .tr = 0, .rcv_left_window_edge = 0, .window_closed = false, - .drf_flag = true, + .drf_flag = false, }; #define stats_get(name, sv, retval) \ From d16d152179f732099b01d220540e411f3f7a92da Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 25 Oct 2018 11:52:39 +0200 Subject: [PATCH 21/40] Fix DRF required init --- kernel/dtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dtp.c b/kernel/dtp.c index 66b35b7afc..00c2c71fe9 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -65,7 +65,7 @@ static struct dtp_sv default_sv = { .rexmsn_ctrl = false, .rate_based = false, .window_based = false, - .drf_required = true, + .drf_required = false, .rate_fulfiled = false, .max_flow_pdu_size = UINT_MAX, .max_flow_sdu_size = UINT_MAX, From 73c584206ae5420cd6072809765605bdae4fe437 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 25 Oct 2018 12:17:39 +0200 Subject: [PATCH 22/40] Undo fix DRF init --- kernel/dtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/dtp.c b/kernel/dtp.c index 00c2c71fe9..14181b6b91 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -65,7 +65,7 @@ static struct dtp_sv default_sv = { .rexmsn_ctrl = false, .rate_based = false, .window_based = false, - .drf_required = false, + .drf_required = true, .rate_fulfiled = false, .max_flow_pdu_size = UINT_MAX, .max_flow_sdu_size = UINT_MAX, @@ -75,7 +75,7 @@ static struct dtp_sv default_sv = { .tr = 0, .rcv_left_window_edge = 0, .window_closed = false, - .drf_flag = false, + .drf_flag = true, }; #define stats_get(name, sv, retval) \ From f3b0f66007fe6847cd195af3884bd7785c1f4cb4 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 25 Oct 2018 14:54:03 +0200 Subject: [PATCH 23/40] Fix bug with RTTQ when there is RTXQ --- kernel/dtp.c | 4 +++- kernel/efcp.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/dtp.c b/kernel/dtp.c index 14181b6b91..750a5ba69d 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1566,7 +1566,9 @@ int dtp_receive(struct dtp * instance, instance->sv->drf_required = false; instance->sv->rcv_left_window_edge = seq_num; dtp_squeue_flush(instance); - rttq_flush(instance->rttq); + if (instance->rttq) { + rttq_flush(instance->rttq); + } spin_unlock_bh(&instance->sv_lock); if (dtcp) { if (dtcp_sv_update(dtcp, &du->pci)) { diff --git a/kernel/efcp.c b/kernel/efcp.c index e9cf3f4a5e..537a10f32b 100644 --- a/kernel/efcp.c +++ b/kernel/efcp.c @@ -671,8 +671,9 @@ cep_id_t efcp_connection_create(struct efcp_container * container, return cep_id_bad(); } efcp->dtp->rtxq = rtxq; + efcp->dtp->rttq = NULL; } else { - rttq = rttq_create(); + rttq = rttq_create(); if (!rttq) { LOG_ERR("Failed to create RTT queue"); efcp_destroy(efcp); From 69dfdd08002c1f4272d6a75a10b4f542517ac8e8 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 25 Oct 2018 15:44:31 +0200 Subject: [PATCH 24/40] Fix bug in snd inactivity timer --- kernel/dtp-ps-default.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/dtp-ps-default.c b/kernel/dtp-ps-default.c index 1fa9aa6f30..b84217d6c2 100644 --- a/kernel/dtp-ps-default.c +++ b/kernel/dtp-ps-default.c @@ -213,7 +213,9 @@ int default_sender_inactivity_timer(struct dtp_ps * ps) next_send = dtp->sv->seq_nr_to_send; dtcp->sv->snd_rt_wind_edge = next_send + init_credit; dtcp->sv->rendezvous_sndr = false; - rttq_flush(dtp->rttq); + if (dtp->rttq) { + rttq_flush(dtp->rttq); + } LOG_DBG("Current values:\n\tinit_credit: %u " "max_sent: %u snd_rt_win: %u next_send: %u", From 0ca488c95a62a93e84ee9287d12c50ff8af525f9 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 25 Oct 2018 20:35:26 +0200 Subject: [PATCH 25/40] Add logs to debug RV --- kernel/dtcp-ps-default.c | 5 +---- kernel/dtcp.c | 3 ++- kernel/dtp-utils.c | 3 --- kernel/dtp.c | 1 + 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index a57a91de1b..804cec84ce 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -370,13 +370,11 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) if (dtcp->sv->snd_rt_wind_edge != rcv_rt) { /* TODO what to do? */ } - LOG_DBG("RCVR rendezvous. RCV LWE: %d | RCV RWE: %d || SND LWE: %d | SND RWE: %d", + LOG_DBG("RCVR rendezvous. RCV LWE: %u | RCV RWE: %u || SND LWE: %u | SND RWE: %u", dtcp->parent->sv->rcv_left_window_edge, dtcp->sv->rcvr_rt_wind_edge, snd_lft, snd_rt); dtcp->sv->rcvr_rt_wind_edge = snd_lft + dtcp->sv->rcvr_credit; - //this would be enough as a normal ACK to the RV packet, however, we need something specific for the reliable ACK - //that is, a timer :( } if (dtcp->sv->flow_ctl && dtcp->parent->sv->rate_based) { @@ -403,7 +401,6 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) if (!du) return -1; - LOG_INFO("DTCP Sending FC (CPU: %d)", smp_processor_id()); dump_we(dtcp, &du->pci); if (dtcp_pdu_send(dtcp, du)) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 11a2ebb0ab..354aa17a25 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -237,7 +237,8 @@ static void tf_rendezvous_rcv(struct timer_list * tl) spin_unlock_bh(&dtp->sv_lock); if (start_rv_rcv_timer) { - LOG_INFO("DTCP Sending FC (CPU: %d)", smp_processor_id()); + LOG_INFO("DTCP Sending FC: RCV LWE: %u | RCV RWE: %u", + dtp->sv->rcv_left_window_edge, dtcp->sv->rcvr_rt_wind_edge); /* Send rendezvous PDU and start timer */ ctrl_pdu_send(dtcp, PDU_TYPE_FC, true); rtimer_start(&dtcp->rendezvous_rcv, rv); diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index 316e6924cb..5c06c51011 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -1167,16 +1167,13 @@ int rttq_drop(struct rttq * q, seq_num_t sn) spin_lock_bh(&q->lock); if (list_empty(&q->head)) { - LOG_INFO("RTTQ empty"); spin_unlock_bh(&q->lock); return 0; } cur = list_last_entry(&q->head, struct rtt_entry, next); - LOG_INFO("LAST ENTRY seq num: %u", cur->sn); cur = NULL; list_for_each_entry_safe(cur, n, &q->head, next) { if (cur->sn <= sn) { - LOG_INFO("Seq num removed: %u", cur->sn); rtt_entry_destroy(cur); } else { spin_unlock_bh(&q->lock); diff --git a/kernel/dtp.c b/kernel/dtp.c index 750a5ba69d..b24ed7c5d3 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1563,6 +1563,7 @@ int dtp_receive(struct dtp * instance, } #endif if ((pci_flags_get(&du->pci) & PDU_FLAGS_DATA_RUN)) { + LOG_INFO("Data Run Flag"); instance->sv->drf_required = false; instance->sv->rcv_left_window_edge = seq_num; dtp_squeue_flush(instance); From 34298a1b2c33f6f99eacfbf5353ec8ce82f843b7 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Thu, 25 Oct 2018 21:28:39 +0200 Subject: [PATCH 26/40] Fix bug --- kernel/dtcp.c | 10 +++++++++- kernel/dtp.c | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 354aa17a25..e4398a88f7 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -566,7 +566,15 @@ static int rcv_flow_ctl(struct dtcp * dtcp, rcu_read_unlock(); - rttq_drop(dtcp->parent->rttq, seq-credit); + spin_lock_bh(&dtcp->parent->sv_lock); + if (dtcp->sv->rendezvous_sndr) { + dtcp->sv->rendezvous_sndr = false; + rtimer_stop(&dtcp->parent->timers.rendezvous); + } + spin_unlock_bh(&dtcp->parent->sv_lock); + if (dtcp->parent->rttq) { + rttq_drop(dtcp->parent->rttq, seq-credit); + } LOG_INFO("New RTT estimation: %u", dtcp->parent->sv->tr); return update_window_and_rate(dtcp, du); diff --git a/kernel/dtp.c b/kernel/dtp.c index b24ed7c5d3..09171842e5 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1364,7 +1364,7 @@ int dtp_write(struct dtp * instance, spin_unlock_bh(&instance->sv_lock); if (start_rv_timer) { - LOG_INFO("Window is closed. SND LWE: %d | SND RWE: %d | TR: %d", + LOG_INFO("Window is closed. SND LWE: %u | SND RWE: %u | TR: %u", instance->dtcp->sv->snd_lft_win, instance->dtcp->sv->snd_rt_wind_edge, instance->sv->tr); From c265227d2011341baaef1c494e4c4c622d8df15c Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Fri, 26 Oct 2018 12:49:10 +0200 Subject: [PATCH 27/40] Fix bug and remove unused logging function --- kernel/dtcp-ps-default.c | 3 --- kernel/dtcp.c | 52 ---------------------------------------- kernel/dtcp.h | 1 - kernel/dtp-utils.c | 29 ---------------------- kernel/dtp-utils.h | 1 - 5 files changed, 86 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 804cec84ce..2ccab5f000 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -167,7 +167,6 @@ int default_receiving_flow_control(struct dtcp_ps * ps, const struct pci * pci) return -1; LOG_DBG("DTCP Sending FC (CPU: %d)", smp_processor_id()); - dump_we(dtcp, &du->pci); if (dtcp_pdu_send(dtcp, du)) return -1; @@ -401,8 +400,6 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) if (!du) return -1; - dump_we(dtcp, &du->pci); - if (dtcp_pdu_send(dtcp, du)) return -1; diff --git a/kernel/dtcp.c b/kernel/dtcp.c index e4398a88f7..c8ca4f823b 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -195,8 +195,6 @@ static int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) } } - dump_we(dtcp, &du->pci); - atomic_dec(&dtcp->cpdus_in_transit); return 0; @@ -387,51 +385,6 @@ struct du * pdu_ctrl_generate(struct dtcp * dtcp, pdu_type_t type) } EXPORT_SYMBOL(pdu_ctrl_generate); -void dump_we(struct dtcp * dtcp, struct pci * pci) -{ - seq_num_t snd_rt_we; - seq_num_t snd_lf_we; - seq_num_t rcv_rt_we; - seq_num_t rcv_lf_we; - seq_num_t new_rt_we; - seq_num_t new_lf_we; - seq_num_t pci_seqn; - seq_num_t my_rt_we; - seq_num_t my_lf_we; - seq_num_t ack; - uint_t rate; - uint_t tframe; - - ASSERT(dtcp); - ASSERT(pci); - - spin_lock_bh(&dtcp->parent->sv_lock); - snd_rt_we = dtcp->sv->snd_rt_wind_edge; - snd_lf_we = dtcp->sv->snd_lft_win; - rcv_rt_we = dtcp->sv->rcvr_rt_wind_edge; - rcv_lf_we = dtcp->parent->sv->rcv_left_window_edge; - spin_unlock_bh(&dtcp->parent->sv_lock); - - new_rt_we = pci_control_new_rt_wind_edge(pci); - new_lf_we = pci_control_new_left_wind_edge(pci); - my_lf_we = pci_control_my_left_wind_edge(pci); - my_rt_we = pci_control_my_rt_wind_edge(pci); - pci_seqn = pci_sequence_number_get(pci); - ack = pci_control_ack_seq_num(pci); - rate = pci_control_sndr_rate(pci); - tframe = pci_control_time_frame(pci); - - LOG_DBG("SEQN: %u N/Ack: %u SndRWE: %u SndLWE: %u " - "RcvRWE: %u RcvLWE: %u " - "newRWE: %u newLWE: %u " - "myRWE: %u myLWE: %u " - "rate: %u tframe: %u", - pci_seqn, ack, snd_rt_we, snd_lf_we, rcv_rt_we, rcv_lf_we, - new_rt_we, new_lf_we, my_rt_we, my_lf_we, - rate, tframe); -} -EXPORT_SYMBOL(dump_we); - /* not a policy according to specs */ static int rcv_nack_ctl(struct dtcp * dtcp, struct du * du) @@ -463,7 +416,6 @@ static int rcv_nack_ctl(struct dtcp * dtcp, rcu_read_unlock(); LOG_DBG("DTCP received NACK (CPU: %d)", smp_processor_id()); - dump_we(dtcp, &du->pci); du_destroy(du); @@ -489,7 +441,6 @@ static int rcv_ack(struct dtcp * dtcp, LOG_DBG("DTCP received ACK (CPU: %d)", smp_processor_id()); - dump_we(dtcp, &du->pci); du_destroy(du); @@ -537,8 +488,6 @@ static int update_window_and_rate(struct dtcp * dtcp, push_pdus_rmt(dtcp); - dump_we(dtcp, &du->pci); - du_destroy(du); return 0; @@ -619,7 +568,6 @@ static int rcvr_rendezvous(struct dtcp * dtcp, rcu_read_unlock(); LOG_INFO("DTCP received Rendezvous (CPU: %d)", smp_processor_id()); - dump_we(dtcp, &du->pci); du_destroy(du); diff --git a/kernel/dtcp.h b/kernel/dtcp.h index b7a1bd0a7a..2a68c13d48 100644 --- a/kernel/dtcp.h +++ b/kernel/dtcp.h @@ -69,7 +69,6 @@ struct dtcp *dtcp_from_component(struct rina_component *component); struct dtcp_ps *dtcp_ps_get(struct dtcp *dtcp); pdu_type_t pdu_ctrl_type_get(struct dtcp *dtcp, seq_num_t seq); struct du *pdu_ctrl_create_ni(struct dtcp *dtcp, pdu_type_t type); -void dump_we(struct dtcp *dtcp, struct pci *pci); int dtcp_pdu_send(struct dtcp *dtcp, struct du *du); struct du *pdu_ctrl_ack_create(struct dtcp *dtcp, seq_num_t last_ctrl_seq_rcvd, diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index 5c06c51011..a3e148dfba 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -341,35 +341,6 @@ void cwq_deliver(struct cwq * queue, return; } -/* NOTE: used only by dump_we */ -seq_num_t cwq_peek(struct cwq * queue) -{ - seq_num_t ret; - struct du * du; - - spin_lock_bh(&queue->lock); - if (rqueue_is_empty(queue->q)){ - spin_unlock_bh(&queue->lock); - return 0; - } - - du = (struct du *) rqueue_head_pop(queue->q); - if (!du) { - spin_unlock_bh(&queue->lock); - return -1; - } - - ret = pci_sequence_number_get(&du->pci); - if (rqueue_head_push_ni(queue->q, du)) { - spin_unlock_bh(&queue->lock); - du_destroy(du); - return ret; - } - spin_unlock_bh(&queue->lock); - - return ret; -} - static struct rtxq_entry * rtxq_entry_create_gfp(struct du * du, gfp_t flag) { struct rtxq_entry * tmp; diff --git a/kernel/dtp-utils.h b/kernel/dtp-utils.h index c207758c5b..e102d2af7a 100644 --- a/kernel/dtp-utils.h +++ b/kernel/dtp-utils.h @@ -44,7 +44,6 @@ ssize_t cwq_size(struct cwq * q); void cwq_deliver(struct cwq * queue, struct dtp * dtp, struct rmt * rmt); -seq_num_t cwq_peek(struct cwq * queue); struct rtxq; From 368b847aa968a099d8206bcf03b1a4c289e3873a Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Fri, 26 Oct 2018 14:47:52 +0200 Subject: [PATCH 28/40] Change the way ctrl PDUs are sent in Rendezvous at receiver --- kernel/dtcp-ps-default.c | 10 +++------- kernel/dtcp.c | 3 ++- kernel/dtcp.h | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 2ccab5f000..39ad141f7f 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -340,7 +340,6 @@ int default_rtt_estimator_nortx(struct dtcp_ps * ps, seq_num_t sn) int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) { struct dtcp * dtcp; - struct du * du; seq_num_t rcv_lft, rcv_rt, snd_lft, snd_rt; timeout_t rv; @@ -396,14 +395,11 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) rv = jiffies_to_msecs(dtcp->parent->sv->tr); rtimer_start(&dtcp->rendezvous_rcv, rv); } - du = pdu_ctrl_generate(dtcp, PDU_TYPE_FC); - if (!du) - return -1; - if (dtcp_pdu_send(dtcp, du)) - return -1; + atomic_inc(&dtcp->cpdus_in_transit); + LOG_INFO("DTCP Sending Rendezvous (CPU: %d)", smp_processor_id()); - return 0; + return ctrl_pdu_send(dtcp, PDU_TYPE_FC, true); } struct ps_base * dtcp_ps_default_create(struct rina_component * component) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index c8ca4f823b..2ac1e03078 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -171,7 +171,7 @@ RINA_SYSFS_OPS(dtcp); RINA_ATTRS(dtcp, rtt, srtt, rttvar, ps_name); RINA_KTYPE(dtcp); -static int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) +int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) { struct du * du; @@ -238,6 +238,7 @@ static void tf_rendezvous_rcv(struct timer_list * tl) LOG_INFO("DTCP Sending FC: RCV LWE: %u | RCV RWE: %u", dtp->sv->rcv_left_window_edge, dtcp->sv->rcvr_rt_wind_edge); /* Send rendezvous PDU and start timer */ + atomic_inc(&dtcp->cpdus_in_transit); ctrl_pdu_send(dtcp, PDU_TYPE_FC, true); rtimer_start(&dtcp->rendezvous_rcv, rv); } diff --git a/kernel/dtcp.h b/kernel/dtcp.h index 2a68c13d48..2225a71a58 100644 --- a/kernel/dtcp.h +++ b/kernel/dtcp.h @@ -82,7 +82,7 @@ bool dtcp_rate_exceeded(struct dtcp *dtcp, int send); /* end SDK */ int pdus_sent_in_t_unit_set(struct dtcp *dtcp, uint_t s); - +int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct); /*FIXME: wrapper to be called by dtp in the post_worker */ int dtcp_sending_ack_policy(struct dtcp *dtcp); #endif From de04a9cf8cf88ba45c5a7b4bf43d058f329e6b48 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Tue, 30 Oct 2018 20:33:03 +0100 Subject: [PATCH 29/40] Add debug logs --- kernel/dtcp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 2ac1e03078..b5cf61c945 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -337,6 +337,13 @@ static int populate_ctrl_pci(struct pci * pci, } return 0; case PDU_TYPE_RENDEZVOUS: + { + LOG_INFO("sndLWE: %u, sndRWE: %u, rcvLWE: %u, rcvRWE: %u", + pci_control_my_left_wind_edge(pci), + pci_control_my_rt_wind_edge(pci), + pci_control_new_left_wind_edge(pci), + pci_control_new_rt_wind_edge(pci)); + } case PDU_TYPE_CACK: if (pci_control_last_seq_num_rcvd_set(pci, last_rcv_ctl_seq)) { LOG_ERR("Could not set last ctrl sn rcvd"); @@ -525,7 +532,6 @@ static int rcv_flow_ctl(struct dtcp * dtcp, if (dtcp->parent->rttq) { rttq_drop(dtcp->parent->rttq, seq-credit); } - LOG_INFO("New RTT estimation: %u", dtcp->parent->sv->tr); return update_window_and_rate(dtcp, du); } From f32953d45206e5cecf9790767cc21a6079a96519 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 31 Oct 2018 11:07:52 +0100 Subject: [PATCH 30/40] Fix Rendezvous PDU size calculation --- kernel/dtcp.c | 7 ------- kernel/pci.c | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index b5cf61c945..34726cc50f 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -337,13 +337,6 @@ static int populate_ctrl_pci(struct pci * pci, } return 0; case PDU_TYPE_RENDEZVOUS: - { - LOG_INFO("sndLWE: %u, sndRWE: %u, rcvLWE: %u, rcvRWE: %u", - pci_control_my_left_wind_edge(pci), - pci_control_my_rt_wind_edge(pci), - pci_control_new_left_wind_edge(pci), - pci_control_new_rt_wind_edge(pci)); - } case PDU_TYPE_CACK: if (pci_control_last_seq_num_rcvd_set(pci, last_rcv_ctl_seq)) { LOG_ERR("Could not set last ctrl sn rcvd"); diff --git a/kernel/pci.c b/kernel/pci.c index d2ec6a5800..a5c122ae5c 100644 --- a/kernel/pci.c +++ b/kernel/pci.c @@ -82,6 +82,13 @@ enum pci_field_index { PCI_ACK_FC_TIME_FRAME, PCI_ACK_FC_SIZE, /* pci_rvous */ + PCI_RVOUS_LAST_CSN_RCVD, + PCI_RVOUS_NEW_LWE, + PCI_RVOUS_NEW_RWE, + PCI_RVOUS_MY_LWE, + PCI_RVOUS_MY_RWE, + PCI_RVOUS_SNDR_RATE, + PCI_RVOUS_TIME_FRAME, PCI_RVOUS_SIZE, /* number of fields */ PCI_FIELD_INDEX_MAX, From 2d7922c89808b40b0283ea530f791d3617ad1993 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 31 Oct 2018 11:13:03 +0100 Subject: [PATCH 31/40] Fix Rendezvous PDU size calculation --- kernel/pci.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/pci.c b/kernel/pci.c index a5c122ae5c..ac4c009abb 100644 --- a/kernel/pci.c +++ b/kernel/pci.c @@ -177,6 +177,11 @@ ssize_t *pci_offset_table_create(struct dt_cons *dt_cons) case PCI_ACK_FC_NEW_RWE: case PCI_ACK_FC_MY_LWE: case PCI_ACK_FC_MY_RWE: + case PCI_RVOUS_LAST_CSN_RCVD: + case PCI_RVOUS_NEW_LWE: + case PCI_RVOUS_NEW_RWE: + case PCI_RVOUS_MY_LWE: + case PCI_RVOUS_MY_RWE: offset += dt_cons->seq_num_length; break; case PCI_CTRL_SN: @@ -190,11 +195,13 @@ ssize_t *pci_offset_table_create(struct dt_cons *dt_cons) case PCI_FC_SNDR_RATE: case PCI_CACK_SNDR_RATE: case PCI_ACK_FC_SNDR_RATE: + case PCI_RVOUS_SNDR_RATE: offset += dt_cons->rate_length; break; case PCI_FC_TIME_FRAME: case PCI_CACK_TIME_FRAME: case PCI_ACK_FC_TIME_FRAME: + case PCI_RVOUS_TIME_FRAME: offset += dt_cons->frame_length; break; case PCI_DT_MGMT_SIZE: From b8f6a736c9cb8cf9dddefa6f8a719526403026ae Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 31 Oct 2018 13:25:18 +0100 Subject: [PATCH 32/40] Add debug logs --- kernel/dtcp-ps-default.c | 2 +- kernel/dtcp.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 39ad141f7f..42cca16707 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -397,7 +397,7 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) } atomic_inc(&dtcp->cpdus_in_transit); - LOG_INFO("DTCP Sending Rendezvous (CPU: %d)", smp_processor_id()); + LOG_INFO("DTCP 1st Sending FC to stop Rendezvous (CPU: %d)", smp_processor_id()); return ctrl_pdu_send(dtcp, PDU_TYPE_FC, true); } diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 34726cc50f..d68710579d 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -175,11 +175,18 @@ int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) { struct du * du; + if (dtcp->sv->rendezvous_rcvr) { + LOG_INFO("Generating FC PDU in RV at RCVR"); + } + du = pdu_ctrl_generate(dtcp, type); if (!du) { atomic_dec(&dtcp->cpdus_in_transit); return -1; } + if (dtcp->sv->rendezvous_rcvr) { + LOG_INFO("Generated FC PDU in RV at RCVR"); + } if (direct) { if (dtp_pdu_send(dtcp->parent, dtcp->rmt, du)){ From a227d9fbef699190b6c5d7b14dc3f0ebade25539 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 31 Oct 2018 13:35:38 +0100 Subject: [PATCH 33/40] Add more debug logs --- kernel/dtp-utils.c | 3 +++ kernel/rmt.c | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index a3e148dfba..2b9c3d445e 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -917,6 +917,9 @@ int dtp_pdu_send(struct dtp * dtp, /* Remote flow case */ if (pci_source(&du->pci) != pci_destination(&du->pci)) { + if (dtp->dtcp->sv->rendezvous_rcvr) { + LOG_INFO("Sending to RMT in RV at RCVR"); + } if (rmt_send(rmt, du)) { LOG_ERR("Problems sending PDU to RMT"); return -1; diff --git a/kernel/rmt.c b/kernel/rmt.c index 817bc061eb..ae31daf1aa 100644 --- a/kernel/rmt.c +++ b/kernel/rmt.c @@ -910,17 +910,18 @@ int rmt_send_port_id(struct rmt *instance, break; case RMT_PS_ENQ_DROP: n1_port->stats.drop_pdus++; - LOG_DBG("PDU dropped while enqueing"); + LOG_ERR("PDU dropped while enqueing"); ret = 0; break; case RMT_PS_ENQ_ERR: n1_port->stats.err_pdus++; - LOG_DBG("Some error occurred while enqueuing PDU"); + LOG_ERR("Some error occurred while enqueuing PDU"); ret = 0; break; case RMT_PS_ENQ_SEND: if (must_enqueue) { /* Wrong behaviour of the policy */ + LOG_ERR("Wrong behaviour of the policy"); du_destroy(du); n1_port->stats.err_pdus++; LOG_DBG("Policy should have enqueue, returned SEND"); From 55095c47726d1367f3797d26393bdc98b7ee1f87 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 31 Oct 2018 19:23:38 +0100 Subject: [PATCH 34/40] Fix bug in handling of PDUs after a restart of a device --- kernel/dtcp.c | 2 +- kernel/ipcps/shim-eth-vlan-core.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index d68710579d..84b6a46be1 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -517,7 +517,7 @@ static int rcv_flow_ctl(struct dtcp * dtcp, struct dtcp_ps, base); LOG_DBG("DTCP received FC (CPU: %d)", smp_processor_id()); - LOG_INFO("New RWE: %u, Credit: %u, Seq Num RTT: %u", seq, credit, seq-credit); + LOG_DBG("New RWE: %u, Credit: %u, Seq Num RTT: %u", seq, credit, seq-credit); if (!ps->rtx_ctrl && ps->rtt_estimator) ps->rtt_estimator(ps, seq - credit); diff --git a/kernel/ipcps/shim-eth-vlan-core.c b/kernel/ipcps/shim-eth-vlan-core.c index 1baa8c8004..17b03a09dd 100644 --- a/kernel/ipcps/shim-eth-vlan-core.c +++ b/kernel/ipcps/shim-eth-vlan-core.c @@ -1798,6 +1798,10 @@ static int eth_vlan_netdev_notify(struct notifier_block *nb, case NETDEV_UP: LOG_INFO("Device %s goes up", dev->name); ntfy_user_ipcp_on_if_state_change(pos, true); + spin_lock_bh(&pos->lock); + pos->tx_busy = 0; + spin_unlock_bh(&pos->lock); + enable_write_all(pos->phy_dev); break; case NETDEV_DOWN: From b0344ff4d2a7ca08ae808b5e1b0f0cbaa167f366 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 7 Nov 2018 15:40:15 +0100 Subject: [PATCH 35/40] Remove redundant code and add extra logs --- kernel/dtcp-ps-default.c | 7 +++++-- kernel/dtcp.c | 6 ------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 42cca16707..3c9c30e6d7 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -179,6 +179,8 @@ int default_rcvr_flow_control(struct dtcp_ps * ps, const struct pci * pci) struct dtcp * dtcp = ps->dm; seq_num_t LWE; seq_num_t RWE; + seq_num_t lwe_p; + seq_num_t rwe_p; if (!dtcp) { LOG_ERR("No instance passed, cannot run policy"); @@ -188,6 +190,8 @@ int default_rcvr_flow_control(struct dtcp_ps * ps, const struct pci * pci) LOG_ERR("No PCI passed, cannot run policy"); return -1; } + lwe_p = pci_control_new_left_wind_edge(pci); + rwe_p = pci_control_new_rt_wind_edge(pci); spin_lock_bh(&dtcp->parent->sv_lock); LWE = dtcp->parent->sv->rcv_left_window_edge; @@ -195,8 +199,7 @@ int default_rcvr_flow_control(struct dtcp_ps * ps, const struct pci * pci) RWE = dtcp->sv->rcvr_rt_wind_edge; spin_unlock_bh(&dtcp->parent->sv_lock); - LOG_DBG("DTCP: %pK", dtcp); - LOG_DBG("LWE: %u RWE: %u", LWE, RWE); + LOG_INFO("DTCP: LWE: %u RWE: %u -- PCI: lwe: %u, rwe: %u", LWE, RWE, lwe_p, rwe_p); return 0; } diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 84b6a46be1..b1b0f73e57 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -523,12 +523,6 @@ static int rcv_flow_ctl(struct dtcp * dtcp, rcu_read_unlock(); - spin_lock_bh(&dtcp->parent->sv_lock); - if (dtcp->sv->rendezvous_sndr) { - dtcp->sv->rendezvous_sndr = false; - rtimer_stop(&dtcp->parent->timers.rendezvous); - } - spin_unlock_bh(&dtcp->parent->sv_lock); if (dtcp->parent->rttq) { rttq_drop(dtcp->parent->rttq, seq-credit); } From 3bf549a976126616829652eed37d5c8b553f8a68 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Wed, 7 Nov 2018 18:52:13 +0100 Subject: [PATCH 36/40] Add extra logs --- kernel/dtcp.c | 4 ++-- kernel/dtp-utils.c | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index b1b0f73e57..d04434f5c4 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -481,6 +481,7 @@ static int update_window_and_rate(struct dtcp * dtcp, rt, tf); } } + LOG_INFO("New SND RWE: %u, New LWE: %u", dtcp->sv->snd_rt_wind_edge, dtcp->sv->snd_lft_win); /* Check if rendezvous timer is active */ cancel_rv_timer = false; @@ -516,8 +517,7 @@ static int rcv_flow_ctl(struct dtcp * dtcp, ps = container_of(rcu_dereference(dtcp->base.ps), struct dtcp_ps, base); - LOG_DBG("DTCP received FC (CPU: %d)", smp_processor_id()); - LOG_DBG("New RWE: %u, Credit: %u, Seq Num RTT: %u", seq, credit, seq-credit); + LOG_DBG("DTCP received FC: New RWE: %u, Credit: %u, Seq Num to drop: %u", seq, credit, seq-credit); if (!ps->rtx_ctrl && ps->rtt_estimator) ps->rtt_estimator(ps, seq - credit); diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index 2b9c3d445e..e09efc5390 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -1144,7 +1144,6 @@ int rttq_drop(struct rttq * q, seq_num_t sn) spin_unlock_bh(&q->lock); return 0; } - cur = list_last_entry(&q->head, struct rtt_entry, next); cur = NULL; list_for_each_entry_safe(cur, n, &q->head, next) { if (cur->sn <= sn) { From 2346fc04ba12ff88d38410909eb554d2b2af86f7 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Tue, 11 Dec 2018 15:33:49 +0100 Subject: [PATCH 37/40] Change logs --- kernel/dtcp-ps-default.c | 4 +++- kernel/dtp.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 3c9c30e6d7..24df4c5eaf 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -199,7 +199,9 @@ int default_rcvr_flow_control(struct dtcp_ps * ps, const struct pci * pci) RWE = dtcp->sv->rcvr_rt_wind_edge; spin_unlock_bh(&dtcp->parent->sv_lock); - LOG_INFO("DTCP: LWE: %u RWE: %u -- PCI: lwe: %u, rwe: %u", LWE, RWE, lwe_p, rwe_p); + if (dtcp->sv->rendezvous_rcvr) { + LOG_INFO("DTCP: LWE: %u RWE: %u -- PCI: lwe: %u, rwe: %u", LWE, RWE, lwe_p, rwe_p); + } return 0; } diff --git a/kernel/dtp.c b/kernel/dtp.c index 09171842e5..5ea81315bf 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1357,6 +1357,8 @@ int dtp_write(struct dtp * instance, if (!instance->dtcp->sv->rendezvous_sndr) { instance->dtcp->sv->rendezvous_sndr = true; + LOG_INFO("RV at the sender %u (CPU: %d)", csn, smp_processor_id()); + /* Start rendezvous timer, wait for Tr to fire */ start_rv_timer = true; rv = jiffies_to_msecs(instance->sv->tr); From 28b50b8d708078847dba7025e3f67879f22a54c3 Mon Sep 17 00:00:00 2001 From: Miquel Tarzan Date: Tue, 11 Dec 2018 19:29:53 +0100 Subject: [PATCH 38/40] New logs --- kernel/dtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 36d802f9ff..8873db299a 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -481,7 +481,7 @@ static int update_window_and_rate(struct dtcp * dtcp, rt, tf); } } - LOG_INFO("New SND RWE: %u, New LWE: %u", dtcp->sv->snd_rt_wind_edge, dtcp->sv->snd_lft_win); + LOG_INFO("New SND RWE: %u, New LWE: %u, DTCP: %pK", dtcp->sv->snd_rt_wind_edge, dtcp->sv->snd_lft_win, dtcp); /* Check if rendezvous timer is active */ cancel_rv_timer = false; From 6f8ba6a577bac84aee83583823b0ce7d00f1853d Mon Sep 17 00:00:00 2001 From: edugrasa Date: Tue, 4 Jun 2019 13:22:48 +0200 Subject: [PATCH 39/40] kernel: dtp/dtcp: fixed rendezvous for retransmission control, moved logs from INFO to DBG --- kernel/dtcp-ps-default.c | 17 +++- kernel/dtcp.c | 53 ++++++++--- kernel/dtp-utils.c | 191 ++++++++++++++++++++++++--------------- kernel/dtp-utils.h | 2 - kernel/dtp.c | 31 +++++-- 5 files changed, 191 insertions(+), 103 deletions(-) diff --git a/kernel/dtcp-ps-default.c b/kernel/dtcp-ps-default.c index 65f1be525c..4fbac7f90d 100644 --- a/kernel/dtcp-ps-default.c +++ b/kernel/dtcp-ps-default.c @@ -111,9 +111,15 @@ int default_sender_ack(struct dtcp_ps * ps, seq_num_t seq_num) } spin_lock_bh(&dtcp->parent->sv_lock); + tr = dtcp->parent->sv->tr; - spin_unlock_bh(&dtcp->parent->sv_lock); + rtxq_ack(dtcp->parent->rtxq, seq_num, tr); + + /* Update LWE */ + dtcp->sv->snd_lft_win = seq_num + 1; + + spin_unlock_bh(&dtcp->parent->sv_lock); } return 0; @@ -200,7 +206,8 @@ int default_rcvr_flow_control(struct dtcp_ps * ps, const struct pci * pci) spin_unlock_bh(&dtcp->parent->sv_lock); if (dtcp->sv->rendezvous_rcvr) { - LOG_INFO("DTCP: LWE: %u RWE: %u -- PCI: lwe: %u, rwe: %u", LWE, RWE, lwe_p, rwe_p); + LOG_DBG("DTCP: LWE: %u RWE: %u -- PCI: lwe: %u, rwe: %u", + LWE, RWE, lwe_p, rwe_p); } return 0; @@ -313,6 +320,9 @@ int default_rtt_estimator(struct dtcp_ps * ps, seq_num_t sn) if (start_time == 0) { LOG_DBG("RTTestimator: PDU %u has been retransmitted", sn); return 0; + } else if (start_time == -1) { + /* The PDU being ACKed is no longer in the RTX queue */ + return -1; } rtt_calculation(ps, start_time); @@ -404,7 +414,8 @@ int default_rcvr_rendezvous(struct dtcp_ps * ps, const struct pci * pci) } atomic_inc(&dtcp->cpdus_in_transit); - LOG_INFO("DTCP 1st Sending FC to stop Rendezvous (CPU: %d)", smp_processor_id()); + LOG_DBG("DTCP 1st Sending FC to stop Rendezvous (CPU: %d)", + smp_processor_id()); return ctrl_pdu_send(dtcp, PDU_TYPE_FC, true); } diff --git a/kernel/dtcp.c b/kernel/dtcp.c index 232f32435d..a3624be5b5 100644 --- a/kernel/dtcp.c +++ b/kernel/dtcp.c @@ -176,7 +176,7 @@ int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) struct du * du; if (dtcp->sv->rendezvous_rcvr) { - LOG_INFO("Generating FC PDU in RV at RCVR"); + LOG_DBG("Generating FC PDU in RV at RCVR"); } du = pdu_ctrl_generate(dtcp, type); @@ -185,7 +185,7 @@ int ctrl_pdu_send(struct dtcp * dtcp, pdu_type_t type, bool direct) return -1; } if (dtcp->sv->rendezvous_rcvr) { - LOG_INFO("Generated FC PDU in RV at RCVR"); + LOG_DBG("Generated FC PDU in RV at RCVR"); } if (direct) { @@ -219,7 +219,7 @@ static void tf_rendezvous_rcv(struct timer_list * tl) bool start_rv_rcv_timer; timeout_t rv; - LOG_INFO("Running rendezvous-at-receiver timer..."); + LOG_DBG("Running rendezvous-at-receiver timer..."); #if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) dtcp = (struct dtcp *) data; #else @@ -242,11 +242,14 @@ static void tf_rendezvous_rcv(struct timer_list * tl) spin_unlock_bh(&dtp->sv_lock); if (start_rv_rcv_timer) { - LOG_INFO("DTCP Sending FC: RCV LWE: %u | RCV RWE: %u", - dtp->sv->rcv_left_window_edge, dtcp->sv->rcvr_rt_wind_edge); + LOG_DBG("DTCP Sending FC: RCV LWE: %u | RCV RWE: %u", + dtp->sv->rcv_left_window_edge, + dtcp->sv->rcvr_rt_wind_edge); + /* Send rendezvous PDU and start timer */ - atomic_inc(&dtcp->cpdus_in_transit); - ctrl_pdu_send(dtcp, PDU_TYPE_FC, true); + atomic_inc(&dtcp->cpdus_in_transit); + ctrl_pdu_send(dtcp, PDU_TYPE_FC, true); + rtimer_start(&dtcp->rendezvous_rcv, rv); } @@ -442,12 +445,21 @@ static int rcv_ack(struct dtcp * dtcp, rcu_read_lock(); ps = container_of(rcu_dereference(dtcp->base.ps), struct dtcp_ps, base); - if (ps->rtx_ctrl && ps->rtt_estimator) - ps->rtt_estimator(ps, pci_control_ack_seq_num(&du->pci)); + if (ps->rtx_ctrl && ps->rtt_estimator) { + if (ps->rtt_estimator(ps, + pci_control_ack_seq_num(&du->pci)) == -1) { + /* Don't process this PDU anymore, it is ACKing a + * DT PDU that is not in the RTX queue (was already + * discarded) + */ + rcu_read_unlock(); + return 0; + } + } + ret = ps->sender_ack(ps, seq); rcu_read_unlock(); - LOG_DBG("DTCP received ACK (CPU: %d)", smp_processor_id()); du_destroy(du); @@ -489,7 +501,7 @@ static int update_window_and_rate(struct dtcp * dtcp, if (dtcp->sv->rendezvous_sndr) { dtcp->sv->rendezvous_sndr = false; cancel_rv_timer = true; - LOG_INFO("Stopping rendezvous timer"); + LOG_DBG("Stopping rendezvous timer"); } spin_unlock_bh(&dtcp->parent->sv_lock); @@ -543,11 +555,22 @@ static int rcv_ack_and_flow_ctl(struct dtcp * dtcp, rcu_read_lock(); ps = container_of(rcu_dereference(dtcp->base.ps), struct dtcp_ps, base); + + if (ps->rtx_ctrl && ps->rtt_estimator) { + if (ps->rtt_estimator(ps, seq) == -1) { + /* Don't process this PDU anymore, it is ACKing a + * DT PDU that is not in the RTX queue (was already + * discarded) + */ + rcu_read_unlock(); + return 0; + } + } + /* This updates sender LWE */ - if (ps->rtx_ctrl && ps->rtt_estimator) - ps->rtt_estimator(ps, seq); if (ps->sender_ack(ps, seq)) LOG_ERR("Could not update RTXQ and LWE"); + rcu_read_unlock(); LOG_DBG("DTCP received ACK-FC (CPU: %d)", smp_processor_id()); @@ -570,7 +593,7 @@ static int rcvr_rendezvous(struct dtcp * dtcp, ret = 0; rcu_read_unlock(); - LOG_INFO("DTCP received Rendezvous (CPU: %d)", smp_processor_id()); + LOG_DBG("DTCP received Rendezvous (CPU: %d)", smp_processor_id()); du_destroy(du); @@ -787,7 +810,7 @@ EXPORT_SYMBOL(dtcp_ack_flow_control_pdu_send); int dtcp_rendezvous_pdu_send(struct dtcp * dtcp) { atomic_inc(&dtcp->cpdus_in_transit); - LOG_INFO("DTCP Sending Rendezvous (CPU: %d)", smp_processor_id()); + LOG_DBG("DTCP Sending Rendezvous (CPU: %d)", smp_processor_id()); return ctrl_pdu_send(dtcp, PDU_TYPE_RENDEZVOUS, true); } EXPORT_SYMBOL(dtcp_rendezvous_pdu_send); diff --git a/kernel/dtp-utils.c b/kernel/dtp-utils.c index 713447ebe9..b4cc2e6830 100644 --- a/kernel/dtp-utils.c +++ b/kernel/dtp-utils.c @@ -37,8 +37,6 @@ #include "rmt.h" #include "dtp-ps.h" -#define RTIMER_ENABLED 1 - /* Maximum retransmission time is 60 seconds */ #define MAX_RTX_WAIT_TIME msecs_to_jiffies(60000) @@ -223,7 +221,6 @@ void cwq_deliver(struct cwq * queue, struct dtp * dtp, struct rmt * rmt) { - struct rtxq * rtxq; struct dtcp * dtcp; struct du * tmp; bool rtx_ctrl; @@ -255,8 +252,7 @@ void cwq_deliver(struct cwq * queue, return; } if (rtx_ctrl) { - rtxq = dtp->rtxq; - if (!rtxq) { + if (!dtp->rtxq) { spin_unlock(&queue->lock); LOG_ERR("Couldn't find the RTX queue"); return; @@ -266,7 +262,7 @@ void cwq_deliver(struct cwq * queue, spin_unlock(&queue->lock); return; } - rtxq_push_ni(rtxq, tmp); + rtxq_push_ni(dtp->rtxq, tmp); } else if (dtp->rttq) { if (rttq_push(dtp->rttq, pci_sequence_number_get(du_pci(du)))) { @@ -387,7 +383,7 @@ static struct rtxqueue * rtxqueue_create_gfp(gfp_t flags) static struct rtxqueue * rtxqueue_create(void) { return rtxqueue_create_gfp(GFP_KERNEL); } -static int rtxqueue_flush(struct rtxqueue * q) +static void rtxqueue_flush(struct rtxqueue * q) { struct rtxq_entry * cur, * n; @@ -397,8 +393,6 @@ static int rtxqueue_flush(struct rtxqueue * q) rtxq_entry_destroy(cur); q->len --; } - - return 0; } static int rtxqueue_destroy(struct rtxqueue * q) @@ -425,7 +419,7 @@ static int rtxqueue_entries_ack(struct rtxqueue * q, seq = pci_sequence_number_get(&cur->du->pci); if (seq <= seq_num) { - LOG_DBG("Seq num acked: %u", seq); + LOG_DBG("Seq num acked: %u. Size %d", seq, q->len); rtxq_entry_destroy(cur); q->len--; } else @@ -509,19 +503,21 @@ unsigned long rtxqueue_entry_timestamp(struct rtxqueue * q, seq_num_t sn) list_for_each_entry(cur, &q->head, next) { csn = pci_sequence_number_get(&cur->du->pci); if (csn > sn) { - LOG_WARN("PDU not in rtxq (duplicate ACK). Received " - "SN: %u, RtxQ SN: %u", sn, csn); - return 0; + LOG_WARN("PDU not in rtxq. Received " + "SN: %u, RtxQ SN: %u. Size: %u", + sn, csn, q->len); + return -1; } if (csn == sn) { /* Ignore time_stamps from retransmitted PDUs */ if (cur->retries != 0) return 0; + return cur->time_stamp; } } - return 0; + return -1; } /* push in seq_num order */ @@ -552,12 +548,12 @@ static int rtxqueue_push_ni(struct rtxqueue * q, struct du * du) if (csn == psn) { LOG_ERR("Another PDU with the same seq_num %u, is in " "the rtx queue!", csn); - return 0; + return -1; } if (csn > psn) { list_add_tail(&tmp->next, &q->head); q->len++; - LOG_DBG("Last PDU with seqnum: %u push to rtxq at: %pk", + LOG_DBG("Last PDU with seqnum: %u push to rtxq at: %pk", csn, q); return 0; } @@ -567,20 +563,20 @@ static int rtxqueue_push_ni(struct rtxqueue * q, struct du * du) if (csn == psn) { LOG_ERR("Another PDU with the same seq_num is in " "the rtx queue!"); - return 0; + return -1; } if (csn > psn) { list_add(&tmp->next, &cur->next); q->len++; - LOG_DBG("Middle PDU with seqnum: %u push to " + LOG_DBG("Middle PDU with seqnum: %u push to " "rtxq at: %pk", csn, q); return 0; } } - LOG_DBG("PDU not pushed!"); + LOG_ERR("PDU not pushed!"); - return 0; + return -1; } /* Exponential backoff after each retransmission */ @@ -595,46 +591,53 @@ static unsigned long time_to_rtx(struct rtxq_entry * cur, unsigned int tr) return cur->time_stamp + rtx_wtime; } -static int rtxqueue_rtx(struct rtxqueue * q, - unsigned int tr, - struct dtp * dtp, - struct rmt * rmt, - uint_t data_rtx_max) +/* Called while holding the rtx queueu lock */ +static int rtxqueue_rtx(struct rtxq * q, + unsigned int tr, + struct dtp * dtp, + uint_t data_rtx_max) { struct rtxq_entry * cur, * n; struct du * tmp; seq_num_t seq = 0; // Used by rbfc. struct dtcp * dtcp; - int sz; - uint_t sc; + int sz, res; + uint_t sc, dropped_sn, dropped_pdus, cwq_max_size; + bool start_rv_timer; + timeout_t rv; ASSERT(q); ASSERT(dt); ASSERT(rmt); dtcp = dtp->dtcp; + dropped_pdus = 0; + dropped_sn = 0; - list_for_each_entry_safe(cur, n, &q->head, next) { + list_for_each_entry_safe(cur, n, &q->queue->head, next) { seq = pci_sequence_number_get(&cur->du->pci); + LOG_DBG("Checking RTX PDU %u, now: %lu >?< %lu + %u", seq, jiffies, cur->time_stamp, tr); + if (time_before_eq(time_to_rtx(cur, tr), jiffies)) { cur->retries++; - cur->time_stamp = jiffies; if (cur->retries >= data_rtx_max) { - LOG_ERR("Maximum number of rtx has been " - "achieved for SeqN %u. Can't " - "maintain QoS", seq); + LOG_WARN("Maximum number of rtx has been " + "achieved for SeqN %u. Dropping " + "PDU, data is lost", seq); rtxq_entry_destroy(cur); - q->len--; - q->drop_pdus++; + q->queue->len--; + q->queue->drop_pdus++; + dropped_pdus++; + if (seq > dropped_sn) + dropped_sn = seq; continue; } - if(dtp && - dtcp && - dtcp_rate_based_fctrl(dtcp->cfg)) { + if (dtp && dtcp && + dtcp_rate_based_fctrl(dtcp->cfg)) { sz = du_data_len(cur->du); sc = dtcp->sv->pdus_sent_in_time_unit; @@ -653,11 +656,15 @@ static int rtxqueue_rtx(struct rtxqueue * q, break; } } + tmp = du_dup_ni(cur->du); - if (dtp_pdu_send(dtp, - rmt, - tmp)) - continue; + + spin_unlock(&q->lock); + res = dtp_pdu_send(dtp, q->rmt, tmp); + spin_lock(&q->lock); + + if (res) continue; + LOG_DBG("Retransmitted PDU with seqN %u", seq); } else { LOG_DBG("RTX timer: from here PDUs still have time," @@ -668,6 +675,46 @@ static int rtxqueue_rtx(struct rtxqueue * q, LOG_DBG("RTXQ %pK has delivered until %u", q, seq); + start_rv_timer = false; + if (dropped_pdus) { + spin_lock_bh(&dtcp->parent->sv_lock); + + /* Move LWE */ + if (dtcp->sv->snd_lft_win < dropped_sn) + dtcp->sv->snd_lft_win = dropped_sn; + + /* TODO, check if we need to move RWE? */ + + /* If RTXQ is empty and CWQ is full, activate rendezvous */ + cwq_max_size = dtcp_max_closed_winq_length(dtcp->cfg); + if (q->queue->len == 0 && + cwq_size(dtcp->parent->cwq) == cwq_max_size) { + /* Check if rendezvous PDU needs to be sent*/ + if (!dtcp->sv->rendezvous_sndr) { + dtcp->sv->rendezvous_sndr = true; + + LOG_DBG("RV at the sender (CPU: %d)", + smp_processor_id()); + + /* Start rendezvous timer, wait for Tr to fire */ + start_rv_timer = true; + rv = jiffies_to_msecs(dtcp->parent->sv->tr); + } + } + + spin_unlock_bh(&dtcp->parent->sv_lock); + } + + if (start_rv_timer) { + LOG_DBG("Window is closed. SND LWE: %u | SND RWE: %u | TR: %u", + dtcp->sv->snd_lft_win, + dtcp->sv->snd_rt_wind_edge, + dtcp->parent->sv->tr); + + /* Send rendezvous PDU and start time */ + rtimer_start(&dtcp->parent->timers.rendezvous, rv); + } + return 0; } @@ -705,22 +752,14 @@ static void rtx_timer_func(struct timer_list * tl) tr = dtp->sv->tr; spin_lock(&q->lock); - if (rtxqueue_rtx(q->queue, - tr, - dtp, - q->rmt, + if (rtxqueue_rtx(q, tr, dtp, dtp->dtcp->cfg->rxctrl_cfg->data_retransmit_max)) LOG_ERR("RTX failed"); -#if RTIMER_ENABLED if (!rtxqueue_empty(q->queue)) rtimer_restart(&dtp->timers.rtx, tr); - LOG_DBG("RTX timer ending..."); -#endif spin_unlock(&q->lock); - - return; } int rtxq_destroy(struct rtxq * q) @@ -753,10 +792,7 @@ struct rtxq * rtxq_create(struct dtp * dtp, if (!tmp) return NULL; -#if RTIMER_ENABLED - //data->data_retransmit_max = dtcp_cfg->rxctrl_cfg->data_retransmit_max; rtimer_init(rtx_timer_func, &dtp->timers.rtx, dtp); -#endif tmp->queue = rtxqueue_create(); if (!tmp->queue) { @@ -818,27 +854,32 @@ EXPORT_SYMBOL(rtxq_entry_timestamp); int rtxq_push_ni(struct rtxq * q, struct du * du) { + int res; + spin_lock_bh(&q->lock); -#if RTIMER_ENABLED + /* is the first transmitted PDU */ rtimer_start(&q->parent->timers.rtx, q->parent->sv->tr); -#endif - rtxqueue_push_ni(q->queue, du); + + res = rtxqueue_push_ni(q->queue, du); + spin_unlock_bh(&q->lock); - return 0; + + return res; } +EXPORT_SYMBOL(rtxq_push_ni); int rtxq_flush(struct rtxq * q) { if (!q || !q->queue) return -1; -#if RTIMER_ENABLED rtimer_stop(&q->parent->timers.rtx); -#endif + spin_lock(&q->lock); rtxqueue_flush(q->queue); spin_unlock(&q->lock); + return 0; } @@ -848,17 +889,20 @@ int rtxq_ack(struct rtxq * q, seq_num_t seq_num, unsigned int tr) { + int res; + if (!q) return -1; spin_lock_bh(&q->lock); - rtxqueue_entries_ack(q->queue, seq_num); -#if RTIMER_ENABLED + + res = rtxqueue_entries_ack(q->queue, seq_num); + rtimer_restart(&q->parent->timers.rtx, tr); -#endif + spin_unlock_bh(&q->lock); - return 0; + return res; } EXPORT_SYMBOL(rtxq_ack); @@ -887,12 +931,11 @@ int rtxq_nack(struct rtxq * q, q->rmt, seq_num, data_retransmit_max); -#if RTIMER_ENABLED if (rtimer_restart(&q->parent->timers.rtx, tr)) { spin_unlock(&q->lock); return -1; } -#endif + spin_unlock(&q->lock); return 0; @@ -907,14 +950,16 @@ int dtp_pdu_send(struct dtp * dtp, /* Remote flow case */ if (pci_source(&du->pci) != pci_destination(&du->pci)) { - if (dtp->dtcp->sv->rendezvous_rcvr) { - LOG_INFO("Sending to RMT in RV at RCVR"); - } - if (rmt_send(rmt, du)) { - LOG_ERR("Problems sending PDU to RMT"); - return -1; - } - return 0; + if (dtp->dtcp->sv->rendezvous_rcvr) { + LOG_INFO("Sending to RMT in RV at RCVR"); + } + + if (rmt_send(rmt, du)) { + LOG_ERR("Problems sending PDU to RMT"); + return -1; + } + + return 0; } /* Local flow case */ diff --git a/kernel/dtp-utils.h b/kernel/dtp-utils.h index 58484e3498..8bdeefb784 100644 --- a/kernel/dtp-utils.h +++ b/kernel/dtp-utils.h @@ -59,8 +59,6 @@ int rtxq_drop_pdus(struct rtxq * q); unsigned long rtxq_entry_timestamp(struct rtxq * q, seq_num_t sn); int rtxq_entry_destroy(struct rtxq_entry * entry); -int rtxq_push_sn(struct rtxq * q, - seq_num_t sn); int rtxq_push_ni(struct rtxq * q, struct du * du); int rtxq_ack(struct rtxq * q, diff --git a/kernel/dtp.c b/kernel/dtp.c index 700380d7ae..6e5a07e06c 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -1258,7 +1258,6 @@ int dtp_write(struct dtp * instance, struct du * du) { struct dtcp * dtcp; - struct rtxq * rtxq; struct du * cdu; struct dtp_ps * ps; seq_num_t sn, csn; @@ -1356,10 +1355,24 @@ int dtp_write(struct dtp * instance, /* Check if rendezvous PDU needs to be sent*/ start_rv_timer = false; spin_lock_bh(&instance->sv_lock); + + /* If there is rtx control and PDUs at the rtxQ + * don't enter the rendezvous state (DTCP will keep + * retransmitting the PDUs until acked or the + * retransmission timeout fires) + */ + if (instance->sv->rexmsn_ctrl && + rtxq_size(instance->rtxq) > 0) { + LOG_DBG("Window is closed but there are PDUs at the RTXQ"); + spin_unlock_bh(&instance->sv_lock); + return 0; + } + + /* Else, check if rendezvous PDU needs to be sent */ if (!instance->dtcp->sv->rendezvous_sndr) { instance->dtcp->sv->rendezvous_sndr = true; - LOG_INFO("RV at the sender %u (CPU: %d)", csn, smp_processor_id()); + LOG_DBG("RV at the sender %u (CPU: %d)", csn, smp_processor_id()); /* Start rendezvous timer, wait for Tr to fire */ start_rv_timer = true; @@ -1368,7 +1381,7 @@ int dtp_write(struct dtp * instance, spin_unlock_bh(&instance->sv_lock); if (start_rv_timer) { - LOG_INFO("Window is closed. SND LWE: %u | SND RWE: %u | TR: %u", + LOG_DBG("Window is closed. SND LWE: %u | SND RWE: %u | TR: %u", instance->dtcp->sv->snd_lft_win, instance->dtcp->sv->snd_rt_wind_edge, instance->sv->tr); @@ -1393,16 +1406,14 @@ int dtp_write(struct dtp * instance, } } if (instance->sv->rexmsn_ctrl) { - /* FIXME: Add timer for PDU */ - rtxq = instance->rtxq; cdu = du_dup_ni(du); if (!cdu) { - LOG_ERR("Failed to copy PDU"); - LOG_ERR("PDU type: %d", pci_type(&du->pci)); + LOG_ERR("Failed to copy PDU. PDU type: %d", + pci_type(&du->pci)); goto pdu_stats_err_exit; } - if (rtxq_push_ni(rtxq, cdu)) { + if (rtxq_push_ni(instance->rtxq, cdu)) { LOG_ERR("Couldn't push to rtxq"); goto pdu_stats_err_exit; } @@ -1567,7 +1578,7 @@ int dtp_receive(struct dtp * instance, } #endif if ((pci_flags_get(&du->pci) & PDU_FLAGS_DATA_RUN)) { - LOG_INFO("Data Run Flag"); + LOG_DBG("Data Run Flag"); instance->sv->drf_required = false; instance->sv->rcv_left_window_edge = seq_num; dtp_squeue_flush(instance); @@ -1636,7 +1647,7 @@ int dtp_receive(struct dtp * instance, #endif /* This is an acceptable data PDU, stop reliable ACK timer */ if (dtcp->sv->rendezvous_rcvr) { - LOG_INFO("RV at receiver put to false"); + LOG_DBG("RV at receiver put to false"); dtcp->sv->rendezvous_rcvr = false; rtimer_stop(&dtcp->rendezvous_rcv); } From 614c7bd8d3266678832c33b6e8961810e9a07d89 Mon Sep 17 00:00:00 2001 From: edugrasa Date: Tue, 4 Jun 2019 15:32:37 +0200 Subject: [PATCH 40/40] kernel: dtp: polished code --- kernel/dtp.c | 42 ++++++++++++++++++++++++------------------ kernel/dtp.h | 2 -- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/kernel/dtp.c b/kernel/dtp.c index 6e5a07e06c..7464dd6bd4 100644 --- a/kernel/dtp.c +++ b/kernel/dtp.c @@ -700,15 +700,16 @@ static void tf_a(struct timer_list * tl) dtp_send_pending_ctrl_pdus(dtp); } else { pci = process_A_expiration(dtp, dtcp); - if (pci) pci_release(pci); -#if DTP_INACTIVITY_TIMERS_ENABLE + + if (pci) + pci_release(pci); + if (rtimer_restart(&dtp->timers.sender_inactivity, 3 * (mpl + r + a))) { LOG_ERR("Failed to start sender_inactiviy timer"); rtimer_start(&dtp->timers.a, a/AF); return; } -#endif } if (!seqq_is_empty(dtp->seqq)) { @@ -1270,13 +1271,10 @@ int dtp_write(struct dtp * instance, efcp = instance->efcp; dtcp = instance->dtcp; -#if DTP_INACTIVITY_TIMERS_ENABLE /* Stop SenderInactivityTimer */ if (rtimer_stop(&instance->timers.sender_inactivity)) { LOG_ERR("Failed to stop timer"); } -#endif - /* Step 1: Delimiting (fragmentation/reassembly) + Protection */ /* * FIXME: The two ways of carrying out flow control @@ -1432,7 +1430,7 @@ int dtp_write(struct dtp * instance, spin_lock_bh(&instance->sv_lock); stats_inc_bytes(tx, instance->sv, sbytes); spin_unlock_bh(&instance->sv_lock); -#if DTP_INACTIVITY_TIMERS_ENABLE + /* Start SenderInactivityTimer */ if (rtimer_restart(&instance->timers.sender_inactivity, 3 * (mpl + r + a ))) { @@ -1440,7 +1438,7 @@ int dtp_write(struct dtp * instance, goto stats_nounlock_err_exit; return -1; } -#endif + return 0; } @@ -1544,10 +1542,12 @@ int dtp_receive(struct dtp * instance, efcp = instance->efcp; spin_lock_bh(&instance->sv_lock); + a = instance->sv->A; r = instance->sv->R; mpl = instance->sv->MPL; LWE = instance->sv->rcv_left_window_edge; + rcu_read_lock(); ps = container_of(rcu_dereference(instance->base.ps), struct dtp_ps, base); @@ -1567,7 +1567,6 @@ int dtp_receive(struct dtp * instance, seq_num, smp_processor_id()); if (instance->sv->drf_required) { -#if DTP_INACTIVITY_TIMERS_ENABLE /* Start ReceiverInactivityTimer */ if (rtimer_restart(&instance->timers.receiver_inactivity, 2 * (mpl + r + a))) { @@ -1576,16 +1575,19 @@ int dtp_receive(struct dtp * instance, du_destroy(du); return -1; } -#endif + if ((pci_flags_get(&du->pci) & PDU_FLAGS_DATA_RUN)) { LOG_DBG("Data Run Flag"); - instance->sv->drf_required = false; + + instance->sv->drf_required = false; instance->sv->rcv_left_window_edge = seq_num; dtp_squeue_flush(instance); if (instance->rttq) { rttq_flush(instance->rttq); } + spin_unlock_bh(&instance->sv_lock); + if (dtcp) { if (dtcp_sv_update(dtcp, &du->pci)) { LOG_ERR("Failed to update dtcp sv"); @@ -1596,13 +1598,16 @@ int dtp_receive(struct dtp * instance, dtp_send_pending_ctrl_pdus(instance); pdu_post(instance, du); stats_inc_bytes(rx, instance->sv, sbytes); - LOG_DBG("Data run flag DRF"); + return 0; } + LOG_ERR("Expecting DRF but not present, dropping PDU %d...", seq_num); + stats_inc(drop, instance->sv); spin_unlock_bh(&instance->sv_lock); + du_destroy(du); return 0; } @@ -1612,14 +1617,15 @@ int dtp_receive(struct dtp * instance, * no need to check presence of in_order or dtcp because in case * they are not, LWE is not updated and always 0 */ - - if ((seq_num <= LWE) || (is_fc_overrun(instance, dtcp, seq_num, sbytes))) - { + if ((seq_num <= LWE) || + (is_fc_overrun(instance, dtcp, seq_num, sbytes))) { /* Duplicate PDU or flow control overrun */ - LOG_ERR("Duplicate PDU or flow control overrun. SN: %u, LWE:%u", + LOG_ERR("Duplicate PDU or flow control overrun.SN: %u, LWE:%u", seq_num, LWE); stats_inc(drop, instance->sv); + spin_unlock_bh(&instance->sv_lock); + du_destroy(du); if (dtcp) { @@ -1635,7 +1641,6 @@ int dtp_receive(struct dtp * instance, return 0; } -#if DTP_INACTIVITY_TIMERS_ENABLE /* Start ReceiverInactivityTimer */ if (rtimer_restart(&instance->timers.receiver_inactivity, 2 * (mpl + r + a ))) { @@ -1644,7 +1649,7 @@ int dtp_receive(struct dtp * instance, du_destroy(du); return -1; } -#endif + /* This is an acceptable data PDU, stop reliable ACK timer */ if (dtcp->sv->rendezvous_rcvr) { LOG_DBG("RV at receiver put to false"); @@ -1716,6 +1721,7 @@ int dtp_receive(struct dtp * instance, instance->sv->rcv_left_window_edge = seq_num; ringq_push(instance->to_post, du); } + spin_unlock_bh(&instance->sv_lock); if (dtcp) { diff --git a/kernel/dtp.h b/kernel/dtp.h index 82a75c5ea1..1472574098 100644 --- a/kernel/dtp.h +++ b/kernel/dtp.h @@ -28,8 +28,6 @@ #include "ps-factory.h" #include "rds/robjects.h" -#define DTP_INACTIVITY_TIMERS_ENABLE 1 - struct dtp * dtp_create(struct efcp * efcp, struct rmt * rmt, struct dtp_config * dtp_cfg,