From c323a5be18670f30055c72e8b247582acd9e6aed Mon Sep 17 00:00:00 2001 From: Arlin Davis Date: Wed, 2 Jul 2014 09:19:43 -0700 Subject: [PATCH] mcm: general cleanup of extra debug code Signed-off-by: Arlin Davis --- dapl/openib_common/mem.c | 1 - dapl/openib_mcm/mix.c | 4 - dapl/svc/mix.c | 20 +---- dapl/svc/mpxy_in.c | 117 +------------------------- dapl/svc/mpxy_out.c | 55 +----------- dapl/svc/mpxyd.c | 17 +--- dapl/svc/mpxyd.h | 10 +-- dat/include/dat2/dat_mic_extensions.h | 5 -- 8 files changed, 8 insertions(+), 221 deletions(-) diff --git a/dapl/openib_common/mem.c b/dapl/openib_common/mem.c index 384dec9..cfc942e 100644 --- a/dapl/openib_common/mem.c +++ b/dapl/openib_common/mem.c @@ -153,7 +153,6 @@ dapls_ib_mr_register(IN DAPL_IA * ia_ptr, " mr_register: ia=%p, lmr=%p va=%p ln=%d pv=0x%x\n", ia_ptr, lmr, virt_addr, length, privileges); - /* TODO: shared memory */ if (lmr->param.mem_type == DAT_MEM_TYPE_SHARED_VIRTUAL) { dapl_dbg_log(DAPL_DBG_TYPE_ERR, " mr_register_shared: NOT IMPLEMENTED\n"); diff --git a/dapl/openib_mcm/mix.c b/dapl/openib_mcm/mix.c index c14492b..d9051a4 100644 --- a/dapl/openib_mcm/mix.c +++ b/dapl/openib_mcm/mix.c @@ -37,8 +37,6 @@ /* * CM proxy services, MCM on MIC to MPXYD via SCIF * - * NOTE: all sync MIX operations for now, TODO async? - * * MIX_IA_OPEN */ int dapli_mix_open(ib_hca_transport_t *tp, char *name, int port, int query_only) @@ -618,7 +616,6 @@ int dapli_mix_cq_free(ib_cq_handle_t m_cq) return 0; } -/* TODO: change for aperture/mapped memory ?? optimize */ int dapli_mix_cq_poll(ib_cq_handle_t m_cq, struct ibv_wc *wc) { /* MPXYD will send event and update EVD, return empty to avoid unnecessary SCIF traffic */ @@ -770,7 +767,6 @@ int dapli_mix_post_recv(ib_qp_handle_t m_qp, int len, struct ibv_recv_wr *wr, st * Separate EP's per thread too avoid locking overhead on SCIF streams */ -/* locate CM object by context, address of object for now--- TODO change to ID */ dp_ib_cm_handle_t dapli_mix_get_cm(ib_hca_transport_t *tp, uint64_t cm_ctx) { dp_ib_cm_handle_t cm = NULL; diff --git a/dapl/svc/mix.c b/dapl/svc/mix.c index cac6435..d2043ab 100644 --- a/dapl/svc/mix.c +++ b/dapl/svc/mix.c @@ -595,7 +595,6 @@ void m_qp_destroy_pi(struct mcm_qp *m_qp) } /* create 2nd qp for proxy-in service, remote is not proxy-in so we need 2 QPs */ -/* TODO: MXS - MSS, CQt will process RR and RW for bi-directional, CQ overflow? create separate CQs? */ int m_qp_create_pi(mcm_scif_dev_t *smd, struct mcm_qp *m_qp) { struct ibv_qp_init_attr qp_create; @@ -609,7 +608,7 @@ int m_qp_create_pi(mcm_scif_dev_t *smd, struct mcm_qp *m_qp) qp_create.cap.max_send_sge = 1; qp_create.cap.max_inline_data = mcm_ib_inline; qp_create.qp_type = IBV_QPT_RC; - qp_create.send_cq = m_qp->m_cq_tx->ib_cq; /* resize CQ ? */ + qp_create.send_cq = m_qp->m_cq_tx->ib_cq; /* signal rate adjusted to avoid CQ overrun */ qp_create.recv_cq = m_qp->m_cq_rx->ib_cq; qp_create.qp_context = (void *)m_qp; @@ -640,20 +639,6 @@ int m_qp_create_pi(mcm_scif_dev_t *smd, struct mcm_qp *m_qp) return 0; } -#ifdef MCM_CQ_TO_RX -/* move m_cq from cqlist to cqrlist for PI service */ -static void m_cq_to_rx(mcm_scif_dev_t *smd, struct mcm_cq *m_cq) -{ - mpxy_lock(&smd->cqlock); - remove_entry(&m_cq->entry); - insert_tail(&m_cq->entry, &smd->cqrlist, m_cq); - m_cq->cq_id = m_cq->entry.tid; - write(smd->md->mc->rx_pipe[1], "w", sizeof("w")); - mlog(8, " cq %p id %d moved to RX cqlist\n", m_cq, m_cq->cq_id); - mpxy_unlock(&smd->cqlock); -} -#endif - static int m_qp_create(mcm_scif_dev_t *smd, struct ibv_qp_init_attr *attr, uint32_t scq_id, @@ -1707,7 +1692,6 @@ static int mix_cm_rep_out(mcm_scif_dev_t *smd, dat_mix_cm_t *pmsg, scif_epd_t sc (system_guid == m_cm->msg.sys_guid)) { mlog(2, " MXS -> MXS local - MODE NOT SUPPORTED, running MXS -> MXS remote mode\n"); - /* TODO: change this to work inside box without IB QP's */ qp = m_cm->m_qp->ib_qp2; dgid = (union ibv_gid *)m_cm->msg.daddr2.gid; dqpn = m_cm->msg.daddr2.qpn; @@ -2076,8 +2060,6 @@ static int mix_post_recv(mcm_scif_dev_t *smd, dat_mix_sr_t *pmsg) if (++m_qp->sr_hd == m_qp->sr_end) m_qp->sr_hd = 0; - /* check, mark full ??? TODO, start hd at 1?? */ - mpxy_unlock(&m_qp->rxlock); return 0; err: diff --git a/dapl/svc/mpxy_in.c b/dapl/svc/mpxy_in.c index da43b5d..8b676ef 100644 --- a/dapl/svc/mpxy_in.c +++ b/dapl/svc/mpxy_in.c @@ -527,54 +527,13 @@ static void m_pi_post_writeto(struct mcm_qp *m_qp, struct mcm_wr_rx *wr_sig, str struct mcm_sr *m_sr = NULL; off_t l_off, l_off_wr, r_off; int ret, i, l_start, l_end, l_len, sg_len, w_len, num_sge, wr_idx, wr_cnt = 0; -#if MCM_PROFILE_DBG - struct mcm_wr_rx *wr_last = NULL; - int lwr_cnt = 0; - int wr_last_idx = 0; - - if (!(wr_sig->flags & M_READ_POSTED)) { - mlog(0, " RR_sig !POSTED[%d]: flgs=0x%x WR[%d,%d-%d,%d] op 0x%x prev %d\n", - wr_sig->w_idx, wr_sig->flags, m_qp->wr_tl_r, m_qp->wr_tl_r_wt, - wr_sig->w_idx, m_qp->wr_hd_r, wc->opcode, m_qp->wt_last_sig); - } -#endif + wr_idx = m_qp->wr_tl_r_wt; /* from WT tail, process RR's posted until reaching wr_last */ while (m_qp->pi_rr_cnt) { /* RR's pending */ wr_rx = (struct mcm_wr_rx *)(m_qp->wrc.wr_addr + (m_qp->wrc.wr_sz * wr_idx)); if (!(wr_rx->flags & M_READ_POSTED)) { - -#if MCM_PROFILE_DBG - if ((wr_rx == wr_sig) || (wr_rx->flags & M_READ_PAUSED)) { - mlog(0, " !POSTED or PAUSE[%d]: flg=0x%x WR[%d,%d-%d,%d] %p LWR[%p->%d,%d]" - " m_qp %p op 0x%x cnt %d,%d prev %d\n", - wr_idx, wr_sig->flags, m_qp->wr_tl_r, m_qp->wr_tl_r_wt, - wr_sig->w_idx, m_qp->wr_hd_r, - wr_rx, wr_last, wr_last ? wr_last->w_idx:0, wr_last_idx, m_qp, - wc->opcode, wr_cnt, lwr_cnt, m_qp->wt_last_sig); - if (!m_qp->wt_err) { /* first error dump list */ - wr_idx = m_qp->wr_tl_r; - while (m_qp->pi_rr_cnt) { - wr_rx = (struct mcm_wr_rx *)(m_qp->wrc.wr_addr + (m_qp->wrc.wr_sz * wr_idx)); - mlog(0, " wr[%d] %p RR(%d,%d,%d) flg %x tl %d tl_wt %d hd %d\n", - wr_rx->w_idx, wr_rx, m_qp->post_cnt_rr, m_qp->stall_cnt_rr, - m_qp->pi_rr_cnt, wr_rx->flags, m_qp->wr_tl_r, m_qp->wr_tl_r_wt, - m_qp->wr_hd_r); - - if (wr_idx == m_qp->wr_hd_r) - break; - - wr_idx = (wr_idx + 1 ) & m_qp->wrc.wr_end; /* next */ - } - m_qp->wt_err = 1; - } - break; - } - lwr_cnt++; - wr_last = wr_rx; - m_qp->wt_last_sig = wr_sig->w_idx; -#endif /* reached RR signaled marker, or head pointer */ if (wr_idx == wr_sig->w_idx || wr_idx == m_qp->wr_hd_r) break; @@ -689,20 +648,12 @@ static void m_pi_post_writeto(struct mcm_qp *m_qp, struct mcm_wr_rx *wr_sig, str wr_rx->flags |= M_READ_WRITE_TO; m_qp->post_cnt_wt++; -#if MCM_PROFILE_DBG - wr_last = wr_rx; - wr_last_idx = wr_idx; -#endif /* reached RR signaled marker, or head */ if (wr_idx == wr_sig->w_idx || wr_idx == m_qp->wr_hd_r) break; wr_idx = (wr_idx + 1) & m_qp->wrc.wr_end; /* next WR */ } -#if MCM_PROFILE_DBG - m_qp->wt_last_sig = wr_sig->w_idx; -#endif - write(smd->md->mc->rx_pipe[1], "w", sizeof "w"); /* signal rx_thread */ return; bail: @@ -725,9 +676,6 @@ void m_pi_pending_wc(struct mcm_qp *m_qp, int *events) /* RR has completed, forward segment to final dst address via SCIF_sendto */ void m_pi_req_event(struct mcm_qp *m_qp, struct mcm_wr_rx *wr_rx, struct ibv_wc *wc, int type) { -#if MCM_PROFILE_DBG - uint32_t delay, pi_ts = mcm_ts_us(); -#endif mlog(4, " WR_rx[%d] %p %s complete po-addr=%p ln=%d, key=%x ctx=%Lx\n", wr_rx->w_idx, wr_rx, wc->opcode == IBV_WC_RDMA_READ ? "RR":"RW_IMM WC", @@ -735,16 +683,6 @@ void m_pi_req_event(struct mcm_qp *m_qp, struct mcm_wr_rx *wr_rx, struct ibv_wc wr_rx->sg[0].lkey, wr_rx->context); mpxy_lock(&m_qp->rxlock); - -#if MCM_PROFILE_DBG - delay = mcm_ts_us() - pi_ts; - if (delay > 200) - mlog(0, " DELAYED (%d): WR_rx[%d] %p %s complete po-addr=%p ln=%d, key=%x ctx=%Lx\n", - delay, wr_rx->w_idx, wr_rx, - wc->opcode == IBV_WC_RDMA_READ ? "RR":"RW_IMM WC", - wr_rx->sg[0].addr, wr_rx->sg[0].length, - wr_rx->sg[0].lkey, wr_rx->context); -#endif if (wc->status && (wc->status != IBV_WC_WR_FLUSH_ERR)) { char *sbuf = (char*)wr_rx->sg[1].addr; @@ -938,35 +876,6 @@ static void m_pi_post_read(struct mcm_qp *m_qp, struct mcm_wr_rx *wr_rx) ib_wr.wr.rdma.rkey, ib_wr.sg_list->addr, ib_wr.sg_list->lkey, m_qp->wr_tl_r, m_qp->wr_hd_r, wr_rx->m_idx); -#if MCM_PROFILE_DBG - if (m_qp->pi_rr_cnt == 1) { - m_qp->rr_last = wr_rx; - m_qp->rr_last_idx = wr_rx->w_idx; - } else if ((m_qp->rr_last == wr_rx) || (((m_qp->rr_last_idx + 1) != wr_rx->w_idx) && wr_rx->w_idx)) { - mlog(0, " ERR: WR Order? wr[%d] %p RR(%d,%d,%d):" - " flgs %x tl %d tl_wt %d hd %d last idx (flg %x op %x) %d %d != %d-1\n", - wr_rx->w_idx, wr_rx, m_qp->post_cnt_rr, m_qp->stall_cnt_rr, m_qp->pi_rr_cnt, - wr_rx->flags, m_qp->wr_tl_r, m_qp->wr_tl_r_wt, m_qp->wr_hd_r, - m_qp->rr_last->flags, m_qp->rr_last->wr.opcode, - m_qp->rr_last_idx_sav, m_qp->rr_last_idx, wr_rx->w_idx); - mlog(0, " ERR: WR[%d] %p RR (%d,%d,%d,%d):" - " flgs 0x%x ln %d r_addr,key %Lx %x to l_addr,key %Lx %x" - " tl %d w_tl %d hd %d\n", - wr_rx->w_idx, wr_rx, m_qp->pi_rr_cnt, - m_qp->pi_rw_cnt, m_qp->post_sig_cnt, m_qp->stall_cnt_rr, - ib_wr.send_flags, l_len, ib_wr.wr.rdma.remote_addr, - ib_wr.wr.rdma.rkey, ib_wr.sg_list->addr, ib_wr.sg_list->lkey, - m_qp->wr_tl_r, m_qp->wr_tl_r_wt, m_qp->wr_hd_r); - - m_qp->rr_last = wr_rx; - m_qp->rr_last_idx_sav = m_qp->rr_last_idx; - m_qp->rr_last_idx = wr_rx->w_idx; - } else { - m_qp->rr_last = wr_rx; - m_qp->rr_last_idx_sav = m_qp->rr_last_idx; - m_qp->rr_last_idx = wr_rx->w_idx; - } -#endif write(smd->md->mc->tx_pipe[1], "w", sizeof "w"); return; bail: @@ -991,30 +900,6 @@ buf_err: void m_pi_rcv_event(struct mcm_qp *m_qp, wrc_idata_t *wrc) { mlog(8," WRC id %x, type %x, flags %x\n", wrc->id, wrc->type, wrc->flags); - -#if MCM_PROFILE_DBG - if (wrc->type == M_WR_TYPE) { - if (!m_qp->wrc_last_idx) - m_qp->wrc_last_idx = wrc->id; - else if ((m_qp->wrc_last_idx == wrc->id) || - (((m_qp->wrc_last_idx + 1) != wrc->id) && (wrc->id != 0))) { - mlog(0," ERR: WR_id %d type %x flgs %x id %d != %d + 1\n", - wrc->id, wrc->type, wrc->flags, wrc->id, m_qp->wrc_last_idx); - m_qp->wrc_last_idx = wrc->id; - } else - m_qp->wrc_last_idx = wrc->id; - } else { - if (!m_qp->wrcc_last_idx) - m_qp->wrcc_last_idx = wrc->id; - else if ((m_qp->wrcc_last_idx == wrc->id) || - (((m_qp->wrcc_last_idx + 1) != wrc->id) && (wrc->id != 0))) { - mlog(0," ERR: WC_id %d type %x flgs %x id %d != %d + 1\n", - wrc->id, wrc->type, wrc->flags, wrc->id, m_qp->wrcc_last_idx); - m_qp->wrcc_last_idx = wrc->id; - } else - m_qp->wrcc_last_idx = wrc->id; - } -#endif if (wrc->type == M_WR_TYPE) { struct mcm_wr_rx *wr_rx; diff --git a/dapl/svc/mpxy_out.c b/dapl/svc/mpxy_out.c index 90c6503..cfd9511 100644 --- a/dapl/svc/mpxy_out.c +++ b/dapl/svc/mpxy_out.c @@ -176,7 +176,7 @@ static int m_po_send_wr_local(struct mcm_qp *m_qp, struct mcm_wr *m_wr, int wr_i ntohll(m_cm->msg.sys_guid), ntohll(system_guid), mcm_map_str(m_cm->msg.daddr1.ep_map)); - return 0; /* TODO */ + return 0; } /* @@ -284,9 +284,6 @@ void m_po_pending_wr(struct mcm_qp *m_qp, int *data, int *events) struct mcm_wr *m_wr; struct ibv_send_wr *bad_wr; int ret, wr_idx, wr_max, poll_cnt, cn_signal; -#if MCM_PROFILE_DBG - int first = 0, last = 0; -#endif mpxy_lock(&m_qp->txlock); if ((m_qp->wr_tl == m_qp->wr_hd) || @@ -294,44 +291,6 @@ void m_po_pending_wr(struct mcm_qp *m_qp, int *data, int *events) mpxy_unlock(&m_qp->txlock); return; } - -#if MCM_PROFILE_DBG - wr_max = 40; - wr_idx = m_qp->wr_tl_rf; - - /* wait for all FS to LS before posting, defer IB RW-RR traffic on first IO */ - while (wr_max) { - m_wr = (struct mcm_wr *)(m_qp->wr_buf + (m_qp->wr_sz * wr_idx)); - if ((m_wr->flags & M_READ_FROM_DONE) && !(m_wr->flags & M_SEND_POSTED)) { - if ((m_wr->flags & M_SEND_FS)) { - mlog(0x4, " FS: qp %p hd %d tl %d idx %d wr %p wr_id %p," - " addr %p sz %d flgs 0x%x\n", - m_qp, m_qp->wr_hd, - m_qp->wr_tl, wr_idx, m_wr, m_wr->org_id, - m_wr->wr.sg_list ? m_wr->wr.sg_list->addr:0, - m_wr->wr.sg_list ? m_wr->sg->length:0, - m_wr->flags); - first = 1; - } - if ((m_wr->flags & M_SEND_LS)) { - mlog(0x10, " LS: qp %p hd %d tl %d idx %d wr %p wr_id %p," - " addr %p sz %d flgs 0x%x\n", - m_qp, m_qp->wr_hd, - m_qp->wr_tl, wr_idx, m_wr, m_wr->org_id, - m_wr->wr.sg_list ? m_wr->wr.sg_list->addr:0, - m_wr->wr.sg_list ? m_wr->sg->length:0, - m_wr->flags); - last = 1; - break; - } - } - if (wr_idx == m_qp->wr_hd) - break; - - wr_idx = (wr_idx + 1) & m_qp->wr_end; - wr_max--; - } -#endif wr_max = 40; wr_idx = m_qp->wr_tl_rf; @@ -386,15 +345,7 @@ void m_po_pending_wr(struct mcm_qp *m_qp, int *data, int *events) } #endif } -#if MCM_PROFILE_DBG - if (!first || !last) { - if (wr_idx == m_qp->wr_hd) - goto done; - wr_idx = (wr_idx + 1) & m_qp->wr_end; - continue; - } -#endif if (!(m_wr->flags & M_SEND_INLINE)) MCNTR(smd->md, MCM_SCIF_READ_FROM_DONE); @@ -481,10 +432,6 @@ void m_po_pending_wr(struct mcm_qp *m_qp, int *data, int *events) m_qp->comp_cnt, m_wr->flags & M_SEND_FS ? "FS": (m_wr->flags & M_SEND_LS) ? "LS":""); -#if MCM_PROFILE_DBG - if (m_wr->flags & M_SEND_LS) - goto done; -#endif } if (!(m_wr->flags & M_SEND_POSTED)) { diff --git a/dapl/svc/mpxyd.c b/dapl/svc/mpxyd.c index 16d59c1..c0d1188 100644 --- a/dapl/svc/mpxyd.c +++ b/dapl/svc/mpxyd.c @@ -818,7 +818,7 @@ void mpxy_tx_thread(void *mic_client) struct mcm_cq *m_cq; struct mcm_qp *m_qp; struct mcm_fd_set *set; - int i, time_ms, data, events, cpu_id, wr_cnt, rf_cnt, rd_cnt, smd_cnt; + int i, time_ms, data, events, cpu_id, smd_cnt; char rbuf[2]; if (mcm_affinity) { @@ -847,7 +847,7 @@ void mpxy_tx_thread(void *mic_client) mpxy_lock(&mc->txlock); mcm_fd_zero(set); mcm_fd_set(mc->tx_pipe[0], set, POLLIN); - data = 0, events = 0, wr_cnt=0, rf_cnt=0, rd_cnt=0, smd_cnt=0; + data = 0, events = 0, smd_cnt=0; for (i=0;imdev[i]; if (md->ibctx == NULL) @@ -887,15 +887,10 @@ void mpxy_tx_thread(void *mic_client) smd = get_next_entry(&smd->entry, &md->smd_list); } mpxy_unlock(&md->slock); - wr_cnt += ((uint64_t *)md->cntrs)[MCM_QP_WRITE]; - rf_cnt += ((uint64_t *)md->cntrs)[MCM_SCIF_READ_FROM]; - rd_cnt += ((uint64_t *)md->cntrs)[MCM_QP_READ_DONE]; } time_ms = smd_cnt ? 0:-1; mpxy_unlock(&mc->txlock); - if (time_ms) mlog(0x10, "TX sleep WR %d RF %d RD %d\n", wr_cnt,rf_cnt,rd_cnt); mcm_select(set, time_ms); - if (time_ms) mlog(0x10, "TX wake WR %d RF %d RD %d\n",wr_cnt,rf_cnt,rd_cnt); if (mcm_poll(mc->tx_pipe[0], POLLIN) == POLLIN) { int cnt = 0; while (read(mc->tx_pipe[0], rbuf, 1) > 0) @@ -1092,7 +1087,7 @@ void mpxy_rx_thread(void *mic_client) struct mcm_cq *m_cq; struct mcm_fd_set *set; char rbuf[2]; - int i, data = 0, cpu_id, time_ms, rr_cnt, wt_cnt; + int i, data = 0, cpu_id, time_ms; if (mcm_affinity) { mpxy_lock(&mc->cplock); @@ -1120,7 +1115,7 @@ void mpxy_rx_thread(void *mic_client) mpxy_lock(&mc->rxlock); mcm_fd_zero(set); mcm_fd_set(mc->rx_pipe[0], set, POLLIN); - data = 0, rr_cnt = 0, wt_cnt = 0; + data = 0; for (i=0;imdev[i]; if (md->ibctx == NULL) @@ -1155,14 +1150,10 @@ void mpxy_rx_thread(void *mic_client) smd = get_next_entry(&smd->entry, &md->smd_list); } mpxy_unlock(&md->slock); - rr_cnt += ((uint64_t *)md->cntrs)[MCM_QP_READ]; - wt_cnt += ((uint64_t *)md->cntrs)[MCM_SCIF_WRITE_TO]; } time_ms = data ? 0:-1; mpxy_unlock(&mc->rxlock); - if (time_ms) mlog(0x20, "RX sleep RR %d WT %d\n",rr_cnt, wt_cnt); mcm_select(set, time_ms); - if (time_ms) mlog(0x20, "RX wake RR %d WT %d\n",rr_cnt, wt_cnt); if (mcm_poll(mc->rx_pipe[0], POLLIN) == POLLIN) read(mc->rx_pipe[0], rbuf, 2); } diff --git a/dapl/svc/mpxyd.h b/dapl/svc/mpxyd.h index 8e9d06e..0bb326c 100644 --- a/dapl/svc/mpxyd.h +++ b/dapl/svc/mpxyd.h @@ -237,15 +237,7 @@ typedef struct mcm_qp { uint32_t last_wr_sig; uint32_t last_wr_pst; #endif -#if MCM_PROFILE_DBG - int wt_err; - int wt_last_sig; - struct mcm_wr_rx *rr_last; - int rr_last_idx; - int rr_last_idx_sav; - int wrc_last_idx; - int wrcc_last_idx; -#endif + } mcm_qp_t; /* DAPL MCM CQ object, id in entry */ diff --git a/dat/include/dat2/dat_mic_extensions.h b/dat/include/dat2/dat_mic_extensions.h index a23b115..2451c91 100755 --- a/dat/include/dat2/dat_mic_extensions.h +++ b/dat/include/dat2/dat_mic_extensions.h @@ -533,11 +533,6 @@ typedef struct dat_mix_qp } __attribute__((packed)) dat_mix_qp_t; /***** MIX CQ operations, create, free, poll, event *****/ -/* - * todo, move polling WC's and notifications to aperture windows - * Might not be needed unless signaling lot's of TX WR's - * - */ typedef struct dat_mix_cq { dat_mix_hdr_t hdr; -- 2.46.0