p4c icon indicating copy to clipboard operation
p4c copied to clipboard

Unexpected warning when compiling with Ghost Thread

Open HeRaNO opened this issue 3 months ago • 4 comments

Compile the following P4 code under p4c 1.2.5.4 (SHA: 17ade03c1 BUILD: Release) (the P4 code is modified from tna_checksum).

#include <core.p4>
#if __TARGET_TOFINO__ == 3
#include <t3na.p4>
#elif __TARGET_TOFINO__ == 2
#include <t2na.p4>
#else
#include <tna.p4>
#endif

#include "common/headers.p4"
#include "common/util.p4"

struct metadata_t {}
Register<bit<32>, bit<32>>(32w2) test;

// ---------------------------------------------------------------------------
// Ingress parser
// ---------------------------------------------------------------------------
parser SwitchIngressParser(
        packet_in pkt,
        out header_t hdr,
        out metadata_t ig_md,
        out ingress_intrinsic_metadata_t ig_intr_md) {

    TofinoIngressParser() tofino_parser;

    state start {
        tofino_parser.apply(pkt, ig_intr_md);
        transition parse_ethernet;
    }

    state parse_ethernet {
        pkt.extract(hdr.ethernet);
        transition select(hdr.ethernet.ether_type) {
            ETHERTYPE_IPV4 : parse_ipv4;
            default : reject;
        }
    }

    state parse_ipv4 {
        pkt.extract(hdr.ipv4);

        transition select(hdr.ipv4.protocol) {
            IP_PROTOCOLS_TCP : parse_tcp;
            IP_PROTOCOLS_UDP : parse_udp;
            default : accept;
        }
    }

    state parse_tcp {
        pkt.extract(hdr.tcp);

        transition accept;
    }

    state parse_udp {
        pkt.extract(hdr.udp);

        transition accept;
    }
}

// ---------------------------------------------------------------------------
// Ingress
// ---------------------------------------------------------------------------
control SwitchIngress(
        inout header_t hdr,
        inout metadata_t ig_md,
        in ingress_intrinsic_metadata_t ig_intr_md,
        in ingress_intrinsic_metadata_from_parser_t ig_prsr_md,
        inout ingress_intrinsic_metadata_for_deparser_t ig_dprsr_md,
        inout ingress_intrinsic_metadata_for_tm_t ig_tm_md) {

    RegisterAction<bit<32>, bit<32>, bit<32>>(test) test_read = {
        void apply(inout bit<32> value, out bit<32> read_value) {
            read_value = value;
        }
    };

    action set_output_port(PortId_t port_id) {
        ig_tm_md.ucast_egress_port = port_id;
    }

    table output_port {
        actions = {
            set_output_port;
        }
    }

    apply {
        test_read.execute(0);
        output_port.apply();
    }
}

// ---------------------------------------------------------------------------
// Ingress Deparser
// ---------------------------------------------------------------------------
control SwitchIngressDeparser(packet_out pkt,
                              inout header_t hdr,
                              in metadata_t ig_md,
                              in ingress_intrinsic_metadata_for_deparser_t 
                                ig_intr_dprsr_md
                              ) {

    apply {
        pkt.emit(hdr);
    }
}

// ---------------------------------------------------------------------------
// Ghost Thread
// ---------------------------------------------------------------------------
control SwitchGhostT(in ghost_intrinsic_metadata_t g_intr_md) {
    RegisterAction<bit<32>, bit<32>, void>(test) test_write = {
        void apply(inout bit<32> value) {
            value = 1;
        }
    };

    apply {
        test_write.execute(0);
    }
}

Pipeline(SwitchIngressParser(),
       SwitchIngress(),
       SwitchIngressDeparser(),
       EmptyEgressParser(),
       EmptyEgress(),
       EmptyEgressDeparser(),
       SwitchGhostT()) pipe;

Switch(pipe) main;

The compiler warns

warning: PHV allocation for unreferenced field 105:ghost::gh_intr_md.$valid<1> ^x ^x pov mocha dark DB0(0) (width 1)

And it crashed when running under open-p4studio (when running run_switchd.sh).

2025-11-18 19:30:14.058810 BF_BFRT ERROR - setGhostTableHandles:1391 table pipe.sfc_reg_qdepth__gen_duplicate_ping_pong was not found in the tableMap for all the tables
2025-11-18 19:30:14.059628 BF_SYS ERROR - ASSERTION FAILED: "0" (0) from setGhostTableHandles:1393
2025-11-18 19:30:14.059949 BF_BFRT ERROR - BfRtInfoImpl:2678 Unable to set the ghost table handle for table pipe.SwitchGhostT.ghost_check_threshold_tbl__gen_duplicate_ping_pong
2025-11-18 19:30:14.060038 BF_BFRT ERROR - setGhostTableHandles:1391 table pipe.sfc_reg_qdepth__gen_duplicate_ping_pong was not found in the tableMap for all the tables
2025-11-18 19:30:14.060098 BF_SYS ERROR - ASSERTION FAILED: "0" (0) from setGhostTableHandles:1393
2025-11-18 19:30:14.060726 BF_BFRT ERROR - BfRtInfoImpl:2678 Unable to set the ghost table handle for table pipe.SwitchIngress.forward__gen_duplicate_ping_pong

~~I wouldn't say it's definitely related, but there might be some connection.~~

UPD: This happens when Ingress reads a global register that is written by Ghost Thread.

HeRaNO avatar Nov 18 '25 11:11 HeRaNO

Can confirm that this issue also happens on the main branch.

p4c 1.2.5.10 (SHA: cceb17da1 BUILD: Release)

HeRaNO avatar Nov 19 '25 07:11 HeRaNO

Updated the full P4 code that can reproduce this issue. @fruffy Would you please take a look?

HeRaNO avatar Nov 20 '25 02:11 HeRaNO

@ChrisDodd Do you maybe know?

fruffy avatar Nov 21 '25 04:11 fruffy

The runtime error is telling you there's no table named pipe.SwitchGhostT.ghost_check_threshold_tbl__gen_duplicate_ping_pong or pipe.SwitchIngress.forward__gen_duplicate_ping_pong in the program or bfrt.json. If you look in the context.json generated for this program, you see that there are "hidden" tables named tbl_p4c5422l22__gen_duplicate_ping_pong and tbl_p4c5422l91__gen_duplicate_ping_pong. Being "hidden" tables it means they are internally generated tables for supporting something in the program, so they should not be visible to the control plane.

This looks to me like some kind of version mismatch/screwup between p4c and open-p4studio -- p4studio is expecting the compiler to set up the ghost ping/pong table in a particular way, and the compiler is actually setting it up in a slightly different way, using different names for the synthetic tables it is generating.

ChrisDodd avatar Nov 23 '25 05:11 ChrisDodd