Is it possible to calculate qdepth in control plane while p4 program is running?

Dear Community

I am working on a P4 program where I am trying to get maximum enqueue while program is running.
I am making a congestion using iperf3 and sending IGMP probing packets from server1 to server2. Every time probing packets are sent I am writing queue information onto the header. All these things happen in Egress pipeline as shown below :

control MyEgress(inout headers hdr,
                 inout metadata meta,
                 inout standard_metadata_t standard_metadata) {
   register<bit<32>>(512) input_port_pkt_count;
    apply {
        if ((hdr.ipv4.protocol != 0x01) && (hdr.ipv4.protocol != 0x6) && (hdr.ipv4.protocol!= 0x11))
    {
           hdr.my_meta.setValid();
           hdr.my_meta.enq_timestamp = standard_metadata.enq_timestamp; 
           hdr.my_meta.enq_qdepth = (bit<32>) standard_metadata.enq_qdepth; 
           //hdr.my_meta.deq_timedelta = standard_metadata.deq_timedelta; 
           hdr.my_meta.deq_qdepth = (bit<32>) standard_metadata.deq_qdepth; 

        bit<32> max_enq;
        bit<32> new_max_enq;
        input_port_pkt_count.read(max_enq, (bit<32>) 0);
        if (((bit<32>)standard_metadata.enq_qdepth - (bit<32>)max_enq > 0))     {
        new_max_enq = (bit<32>)standard_metadata.enq_qdepth;
        input_port_pkt_count.write((bit<32>) 0, new_max_enq);
        hdr.my_meta.deq_timedelta = (bit<32>) standard_metadata.enq_qdepth;
}
      }
 }
}

The results I am getting after the execution are as follows :

('11207707', '63', '63', '62')
('11547558', '60', '60', '62')
('11719366', '61', '61', '58')
('11899297', '59', '59', '63')
('12063840', '64', '64', '59')
('12927379', '63', '63', '59')
('13507326', '58', '58', '55')
('13595418', '63', '63', '62')
('14243367', '63', '0', '61')
('14539535', '61', '61', '62')
('14631315', '61', '0', '58')
('14887811', '61', '0', '56')
('15259559', '59', '59', '58')
('15531324', '61', '61', '62')
('15991441', '57', '57', '58')
('17027418', '62', '62', '60')
('17131323', '60', '60', '59')
('17739281', '61', '61', '62')
('18027368', '60', '60', '63')
('18323845', '59', '59', '61')
('19311303', '61', '61', '59')
('19427347', '63', '63', '62')
('19531319', '60', '60', '63')
('20027498', '61', '61', '63')
('20211469', '63', '63', '62')
('20419335', '62', '62', '60')
('20939643', '59', '59', '59')
('21223827', '62', '62', '57')

The first column is timestamp, the second column is enq_qdepth, the third column is max_enq_qdepth and the last column is deq_qdepth.

My question is : Am I making some mistakes in the algorithm or bmv2 switch is not capable to do calculations?

I can attach the whole program as well if needed.

Kind regards,
Nagmat

You do not initialize new_max_enq, but the BMv2 software switch typically guarantees all variables are initialized to 0 for you, if you do not do so explicitly. I would recommend initializing variables explicitly unless you have very good reasons not to do so.

So whenever this condition is false: (((bit<32>)standard_metadata.enq_qdepth - (bit<32>)max_enq > 0)), there is no assignment to new_max_enq in your code, so it remains at its initial value of 0. Then new_max_enq is written to the register.

I initialized the new_max_enq but the results didn’t change.
My assumption is that : Reading and writing to registers is too slow, that’s why we end up getting the old value of the register.

What did you initialize new_max_enq to?

My guess is that your assumption is incorrect, and that thinking carefully about the normal sequential execution of your P4 code will reveal a bug in your P4 code.

control MyEgress(inout headers hdr,
                 inout metadata meta,
                 inout standard_metadata_t standard_metadata) {
        register<bit<32>>(512) input_port_pkt_count;
        apply {

 if ((hdr.ipv4.protocol != 0x01) && (hdr.ipv4.protocol != 0x6) && (hdr.ipv4.protocol!= 0x11))
    {
           hdr.my_meta.setValid();
           hdr.my_meta.enq_timestamp = standard_metadata.enq_timestamp;
           hdr.my_meta.enq_qdepth = (bit<32>) standard_metadata.enq_qdepth;
        bit<32> max_enq;
        input_port_pkt_count.read(max_enq, (bit<32>) 0);
        if (((bit<32>)standard_metadata.enq_qdepth > (bit<32>)max_enq))     {
        max_enq = (bit<32>)standard_metadata.enq_qdepth ;
        }
        hdr.my_meta.deq_timedelta = (bit<32>) max_enq;
        input_port_pkt_count.write((bit<32>) 0, max_enq);
           hdr.my_meta.deq_qdepth = (bit<32>) standard_metadata.deq_qdepth;
      }
 }
}

This code worked well. The code in the beginning was resulting positive numbers only, that’s why we were always getting the latest values instead of maximum.