X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcxgbe%2Fsge.c;h=8c7dbe3a1d4954903941eca4aa0aa1be027e285a;hb=ecf1474a618ba77ef3c4471fdc004a8c5f3b4d11;hp=3a0eba5df50e8efd8bedce40fe4a2b47c283c7dc;hpb=df68e75a79a4d0f86d0ebea2d43775759e066a2a;p=dpdk.git diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c index 3a0eba5df5..8c7dbe3a1d 100644 --- a/drivers/net/cxgbe/sge.c +++ b/drivers/net/cxgbe/sge.c @@ -73,7 +73,7 @@ static inline unsigned int fl_mtu_bufsize(struct adapter *adapter, { struct sge *s = &adapter->sge; - return CXGBE_ALIGN(s->pktshift + ETHER_HDR_LEN + VLAN_HLEN + mtu, + return CXGBE_ALIGN(s->pktshift + RTE_ETHER_HDR_LEN + VLAN_HLEN + mtu, s->fl_align); } @@ -1004,12 +1004,6 @@ static inline int tx_do_packet_coalesce(struct sge_eth_txq *txq, struct cpl_tx_pkt_core *cpl; struct tx_sw_desc *sd; unsigned int idx = q->coalesce.idx, len = mbuf->pkt_len; - unsigned int max_coal_pkt_num = is_pf4(adap) ? ETH_COALESCE_PKT_NUM : - ETH_COALESCE_VF_PKT_NUM; - -#ifdef RTE_LIBRTE_CXGBE_TPUT - RTE_SET_USED(nb_pkts); -#endif if (q->coalesce.type == 0) { mc = (struct ulp_txpkt *)q->coalesce.ptr; @@ -1082,13 +1076,15 @@ static inline int tx_do_packet_coalesce(struct sge_eth_txq *txq, sd->coalesce.sgl[idx & 1] = (struct ulptx_sgl *)(cpl + 1); sd->coalesce.idx = (idx & 1) + 1; - /* send the coaelsced work request if max reached */ - if (++q->coalesce.idx == max_coal_pkt_num -#ifndef RTE_LIBRTE_CXGBE_TPUT - || q->coalesce.idx >= nb_pkts -#endif - ) + /* Send the coalesced work request, only if max reached. However, + * if lower latency is preferred over throughput, then don't wait + * for coalescing the next Tx burst and send the packets now. + */ + q->coalesce.idx++; + if (q->coalesce.idx == adap->params.max_tx_coalesce_num || + (adap->devargs.tx_mode_latency && q->coalesce.idx >= nb_pkts)) ship_tx_pkt_coalesce_wr(adap, txq); + return 0; } @@ -1128,7 +1124,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf, * The chip min packet length is 10 octets but play safe and reject * anything shorter than an Ethernet header. */ - if (unlikely(m->pkt_len < ETHER_HDR_LEN)) { + if (unlikely(m->pkt_len < RTE_ETHER_HDR_LEN)) { out_free: rte_pktmbuf_free(m); return 0; @@ -1138,14 +1134,15 @@ out_free: (unlikely(m->pkt_len > max_pkt_len))) goto out_free; - pi = (struct port_info *)txq->data->dev_private; + pi = txq->data->dev_private; adap = pi->adapter; cntrl = F_TXPKT_L4CSUM_DIS | F_TXPKT_IPCSUM_DIS; /* align the end of coalesce WR to a 512 byte boundary */ txq->q.coalesce.max = (8 - (txq->q.pidx & 7)) * 8; - if (!((m->ol_flags & PKT_TX_TCP_SEG) || (m->pkt_len > ETHER_MAX_LEN))) { + if (!((m->ol_flags & PKT_TX_TCP_SEG) || + m->pkt_len > RTE_ETHER_MAX_LEN)) { if (should_tx_packet_coalesce(txq, mbuf, &cflits, adap)) { if (unlikely(map_mbuf(mbuf, addr) < 0)) { dev_warn(adap, "%s: mapping err for coalesce\n", @@ -1153,7 +1150,6 @@ out_free: txq->stats.mapping_err++; goto out_free; } - rte_prefetch0((volatile void *)addr); return tx_do_packet_coalesce(txq, mbuf, cflits, adap, pi, addr, nb_pkts); } else { @@ -1230,7 +1226,7 @@ out_free: v6 = (m->ol_flags & PKT_TX_IPV6) != 0; l3hdr_len = m->l3_len; l4hdr_len = m->l4_len; - eth_xtra_len = m->l2_len - ETHER_HDR_LEN; + eth_xtra_len = m->l2_len - RTE_ETHER_HDR_LEN; len += sizeof(*lso); wr->op_immdlen = htonl(V_FW_WR_OP(is_pf4(adap) ? FW_ETH_TX_PKT_WR : @@ -1427,14 +1423,16 @@ int t4_mgmt_tx(struct sge_ctrl_txq *q, struct rte_mbuf *mbuf) /** * alloc_ring - allocate resources for an SGE descriptor ring - * @dev: the PCI device's core device + * @dev: the port associated with the queue + * @z_name: memzone's name + * @queue_id: queue index + * @socket_id: preferred socket id for memory allocations * @nelem: the number of descriptors * @elem_size: the size of each descriptor + * @stat_size: extra space in HW ring for status information * @sw_size: the size of the SW state associated with each ring element * @phys: the physical address of the allocated ring * @metadata: address of the array holding the SW state for the ring - * @stat_size: extra space in HW ring for status information - * @node: preferred node for memory allocations * * Allocates resources for an SGE descriptor ring, such as Tx queues, * free buffer lists, or response queues. Each SGE ring requires @@ -1444,39 +1442,34 @@ int t4_mgmt_tx(struct sge_ctrl_txq *q, struct rte_mbuf *mbuf) * of the function), the bus address of the HW ring, and the address * of the SW ring. */ -static void *alloc_ring(size_t nelem, size_t elem_size, - size_t sw_size, dma_addr_t *phys, void *metadata, - size_t stat_size, __rte_unused uint16_t queue_id, - int socket_id, const char *z_name, - const char *z_name_sw) +static void *alloc_ring(struct rte_eth_dev *dev, const char *z_name, + uint16_t queue_id, int socket_id, size_t nelem, + size_t elem_size, size_t stat_size, size_t sw_size, + dma_addr_t *phys, void *metadata) { size_t len = CXGBE_MAX_RING_DESC_SIZE * elem_size + stat_size; + char z_name_sw[RTE_MEMZONE_NAMESIZE]; const struct rte_memzone *tz; void *s = NULL; + snprintf(z_name_sw, sizeof(z_name_sw), "eth_p%d_q%d_%s_sw_ring", + dev->data->port_id, queue_id, z_name); + dev_debug(adapter, "%s: nelem = %zu; elem_size = %zu; sw_size = %zu; " "stat_size = %zu; queue_id = %u; socket_id = %d; z_name = %s;" " z_name_sw = %s\n", __func__, nelem, elem_size, sw_size, stat_size, queue_id, socket_id, z_name, z_name_sw); - tz = rte_memzone_lookup(z_name); - if (tz) { - dev_debug(adapter, "%s: tz exists...returning existing..\n", - __func__); - goto alloc_sw_ring; - } - /* * Allocate TX/RX ring hardware descriptors. A memzone large enough to * handle the maximum ring size is allocated in order to allow for * resizing in later calls to the queue setup function. */ - tz = rte_memzone_reserve_aligned(z_name, len, socket_id, - RTE_MEMZONE_IOVA_CONTIG, 4096); + tz = rte_eth_dma_zone_reserve(dev, z_name, queue_id, len, 4096, + socket_id); if (!tz) return NULL; -alloc_sw_ring: memset(tz->addr, 0, len); if (sw_size) { s = rte_zmalloc_socket(z_name_sw, nelem * sw_size, @@ -1701,6 +1694,11 @@ int cxgbe_poll(struct sge_rspq *q, struct rte_mbuf **rx_pkts, unsigned int params; u32 val; + if (unlikely(rxq->flags & IQ_STOPPED)) { + *work_done = 0; + return 0; + } + *work_done = process_responses(q, budget, rx_pkts); if (*work_done) { @@ -1761,22 +1759,22 @@ static void __iomem *bar2_address(struct adapter *adapter, unsigned int qid, return adapter->bar2 + bar2_qoffset; } -int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_rspq *rq) +int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_eth_rxq *rxq) { - struct sge_eth_rxq *rxq = container_of(rq, struct sge_eth_rxq, rspq); unsigned int fl_id = rxq->fl.size ? rxq->fl.cntxt_id : 0xffff; + rxq->flags &= ~IQ_STOPPED; return t4_iq_start_stop(adap, adap->mbox, true, adap->pf, 0, - rq->cntxt_id, fl_id, 0xffff); + rxq->rspq.cntxt_id, fl_id, 0xffff); } -int t4_sge_eth_rxq_stop(struct adapter *adap, struct sge_rspq *rq) +int t4_sge_eth_rxq_stop(struct adapter *adap, struct sge_eth_rxq *rxq) { - struct sge_eth_rxq *rxq = container_of(rq, struct sge_eth_rxq, rspq); unsigned int fl_id = rxq->fl.size ? rxq->fl.cntxt_id : 0xffff; + rxq->flags |= IQ_STOPPED; return t4_iq_start_stop(adap, adap->mbox, false, adap->pf, 0, - rq->cntxt_id, fl_id, 0xffff); + rxq->rspq.cntxt_id, fl_id, 0xffff); } /* @@ -1791,22 +1789,16 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, int ret, flsz = 0; struct fw_iq_cmd c; struct sge *s = &adap->sge; - struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private); - char z_name[RTE_MEMZONE_NAMESIZE]; - char z_name_sw[RTE_MEMZONE_NAMESIZE]; + struct port_info *pi = eth_dev->data->dev_private; unsigned int nb_refill; u8 pciechan; /* Size needs to be multiple of 16, including status entry. */ iq->size = cxgbe_roundup(iq->size, 16); - snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s", - eth_dev->data->port_id, queue_id, - fwevtq ? "fwq_ring" : "rx_ring"); - snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name); - - iq->desc = alloc_ring(iq->size, iq->iqe_len, 0, &iq->phys_addr, NULL, 0, - queue_id, socket_id, z_name, z_name_sw); + iq->desc = alloc_ring(eth_dev, fwevtq ? "fwq_ring" : "rx_ring", + queue_id, socket_id, iq->size, iq->iqe_len, + 0, 0, &iq->phys_addr, NULL); if (!iq->desc) return -ENOMEM; @@ -1864,18 +1856,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, fl->size = s->fl_starve_thres - 1 + 2 * 8; fl->size = cxgbe_roundup(fl->size, 8); - snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s", - eth_dev->data->port_id, queue_id, - fwevtq ? "fwq_ring" : "fl_ring"); - snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name); - - fl->desc = alloc_ring(fl->size, sizeof(__be64), + fl->desc = alloc_ring(eth_dev, "fl_ring", queue_id, socket_id, + fl->size, sizeof(__be64), s->stat_len, sizeof(struct rx_sw_desc), - &fl->addr, &fl->sdesc, s->stat_len, - queue_id, socket_id, z_name, z_name_sw); - - if (!fl->desc) - goto fl_nomem; + &fl->addr, &fl->sdesc); + if (!fl->desc) { + ret = -ENOMEM; + goto err; + } flsz = fl->size / 8 + s->stat_len / sizeof(struct tx_desc); c.iqns_to_fl0congen |= @@ -1966,7 +1954,8 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, * simple (and hopefully less wrong). */ if (is_pf4(adap) && !is_t4(adap->params.chip) && cong >= 0) { - u32 param, val; + u8 cng_ch_bits_log = adap->params.arch.cng_ch_bits_log; + u32 param, val, ch_map = 0; int i; param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | @@ -1979,9 +1968,9 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, X_CONMCTXT_CNGTPMODE_CHANNEL); for (i = 0; i < 4; i++) { if (cong & (1 << i)) - val |= V_CONMCTXT_CNGCHMAP(1 << - (i << 2)); + ch_map |= 1 << (i << cng_ch_bits_log); } + val |= V_CONMCTXT_CNGCHMAP(ch_map); } ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); @@ -1995,8 +1984,6 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, refill_fl_err: t4_iq_free(adap, adap->mbox, adap->pf, 0, FW_IQ_TYPE_FL_INT_CAP, iq->cntxt_id, fl->cntxt_id, 0xffff); -fl_nomem: - ret = -ENOMEM; err: iq->cntxt_id = 0; iq->abs_id = 0; @@ -2061,22 +2048,16 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, int ret, nentries; struct fw_eq_eth_cmd c; struct sge *s = &adap->sge; - struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private); - char z_name[RTE_MEMZONE_NAMESIZE]; - char z_name_sw[RTE_MEMZONE_NAMESIZE]; + struct port_info *pi = eth_dev->data->dev_private; u8 pciechan; /* Add status entries */ nentries = txq->q.size + s->stat_len / sizeof(struct tx_desc); - snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s", - eth_dev->data->port_id, queue_id, "tx_ring"); - snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name); - - txq->q.desc = alloc_ring(txq->q.size, sizeof(struct tx_desc), - sizeof(struct tx_sw_desc), &txq->q.phys_addr, - &txq->q.sdesc, s->stat_len, queue_id, - socket_id, z_name, z_name_sw); + txq->q.desc = alloc_ring(eth_dev, "tx_ring", queue_id, socket_id, + txq->q.size, sizeof(struct tx_desc), + s->stat_len, sizeof(struct tx_sw_desc), + &txq->q.phys_addr, &txq->q.sdesc); if (!txq->q.desc) return -ENOMEM; @@ -2140,21 +2121,14 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, int ret, nentries; struct fw_eq_ctrl_cmd c; struct sge *s = &adap->sge; - struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private); - char z_name[RTE_MEMZONE_NAMESIZE]; - char z_name_sw[RTE_MEMZONE_NAMESIZE]; + struct port_info *pi = eth_dev->data->dev_private; /* Add status entries */ nentries = txq->q.size + s->stat_len / sizeof(struct tx_desc); - snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s", - eth_dev->data->port_id, queue_id, "ctrl_tx_ring"); - snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name); - - txq->q.desc = alloc_ring(txq->q.size, sizeof(struct tx_desc), - 0, &txq->q.phys_addr, - NULL, 0, queue_id, - socket_id, z_name, z_name_sw); + txq->q.desc = alloc_ring(eth_dev, "ctrl_tx_ring", queue_id, + socket_id, txq->q.size, sizeof(struct tx_desc), + 0, 0, &txq->q.phys_addr, NULL); if (!txq->q.desc) return -ENOMEM; @@ -2225,15 +2199,18 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, */ void t4_sge_eth_clear_queues(struct port_info *pi) { - int i; struct adapter *adap = pi->adapter; - struct sge_eth_rxq *rxq = &adap->sge.ethrxq[pi->first_qset]; - struct sge_eth_txq *txq = &adap->sge.ethtxq[pi->first_qset]; + struct sge_eth_rxq *rxq; + struct sge_eth_txq *txq; + int i; + rxq = &adap->sge.ethrxq[pi->first_rxqset]; for (i = 0; i < pi->n_rx_qsets; i++, rxq++) { if (rxq->rspq.desc) - t4_sge_eth_rxq_stop(adap, &rxq->rspq); + t4_sge_eth_rxq_stop(adap, rxq); } + + txq = &adap->sge.ethtxq[pi->first_txqset]; for (i = 0; i < pi->n_tx_qsets; i++, txq++) { if (txq->q.desc) { struct sge_txq *q = &txq->q; @@ -2249,7 +2226,7 @@ void t4_sge_eth_clear_queues(struct port_info *pi) void t4_sge_eth_rxq_release(struct adapter *adap, struct sge_eth_rxq *rxq) { if (rxq->rspq.desc) { - t4_sge_eth_rxq_stop(adap, &rxq->rspq); + t4_sge_eth_rxq_stop(adap, rxq); free_rspq_fl(adap, &rxq->rspq, rxq->fl.size ? &rxq->fl : NULL); } } @@ -2266,6 +2243,36 @@ void t4_sge_eth_txq_release(struct adapter *adap, struct sge_eth_txq *txq) } } +void t4_sge_eth_release_queues(struct port_info *pi) +{ + struct adapter *adap = pi->adapter; + struct sge_eth_rxq *rxq; + struct sge_eth_txq *txq; + unsigned int i; + + rxq = &adap->sge.ethrxq[pi->first_rxqset]; + /* clean up Ethernet Tx/Rx queues */ + for (i = 0; i < pi->n_rx_qsets; i++, rxq++) { + /* Free only the queues allocated */ + if (rxq->rspq.desc) { + t4_sge_eth_rxq_release(adap, rxq); + rte_eth_dma_zone_free(rxq->rspq.eth_dev, "fl_ring", i); + rte_eth_dma_zone_free(rxq->rspq.eth_dev, "rx_ring", i); + rxq->rspq.eth_dev = NULL; + } + } + + txq = &adap->sge.ethtxq[pi->first_txqset]; + for (i = 0; i < pi->n_tx_qsets; i++, txq++) { + /* Free only the queues allocated */ + if (txq->q.desc) { + t4_sge_eth_txq_release(adap, txq); + rte_eth_dma_zone_free(txq->eth_dev, "tx_ring", i); + txq->eth_dev = NULL; + } + } +} + void t4_sge_tx_monitor_start(struct adapter *adap) { rte_eal_alarm_set(50, tx_timer_cb, (void *)adap); @@ -2285,21 +2292,6 @@ void t4_sge_tx_monitor_stop(struct adapter *adap) void t4_free_sge_resources(struct adapter *adap) { unsigned int i; - struct sge_eth_rxq *rxq = &adap->sge.ethrxq[0]; - struct sge_eth_txq *txq = &adap->sge.ethtxq[0]; - - /* clean up Ethernet Tx/Rx queues */ - for (i = 0; i < adap->sge.max_ethqsets; i++, rxq++, txq++) { - /* Free only the queues allocated */ - if (rxq->rspq.desc) { - t4_sge_eth_rxq_release(adap, rxq); - rxq->rspq.eth_dev = NULL; - } - if (txq->q.desc) { - t4_sge_eth_txq_release(adap, txq); - txq->eth_dev = NULL; - } - } /* clean up control Tx queues */ for (i = 0; i < ARRAY_SIZE(adap->sge.ctrlq); i++) { @@ -2309,12 +2301,17 @@ void t4_free_sge_resources(struct adapter *adap) reclaim_completed_tx_imm(&cq->q); t4_ctrl_eq_free(adap, adap->mbox, adap->pf, 0, cq->q.cntxt_id); + rte_eth_dma_zone_free(adap->eth_dev, "ctrl_tx_ring", i); + rte_mempool_free(cq->mb_pool); free_txq(&cq->q); } } - if (adap->sge.fw_evtq.desc) + /* clean up firmware event queue */ + if (adap->sge.fw_evtq.desc) { free_rspq_fl(adap, &adap->sge.fw_evtq, NULL); + rte_eth_dma_zone_free(adap->eth_dev, "fwq_ring", 0); + } } /**