From afebf20c2a5616f00c3a8160e2c23a2868954813 Mon Sep 17 00:00:00 2001 From: Ioana Radulescu Date: Fri, 26 Jul 2013 19:46:48 +0300 Subject: dpaa_eth: Remove dpa_bp_count from percpu_priv structure Instead just rely on the percpu field in dpa_bp structure. The performance lost due to the extra indirection is compensated by the smaller size of the percpu_priv structure. This way we begin to eliminate the assumption that private interfaces only have one default buffer pool, which may not remain true for long. Signed-off-by: Ioana Radulescu Change-Id: I0b2c199c3f8883fa7d5fa1a06d2940f8170fc959 Reviewed-on: http://git.am.freescale.net:8181/3655 Reviewed-by: Bucur Madalin-Cristian-B32716 Reviewed-by: Hamciuc Bogdan-BHAMCIU1 Reviewed-by: Fleming Andrew-AFLEMING Tested-by: Fleming Andrew-AFLEMING diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c index dee4384..f84b19e 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c @@ -78,8 +78,8 @@ static int dpa_debugfs_show(struct seq_file *file, void *offset) for_each_online_cpu(i) { percpu_priv = per_cpu_ptr(priv->percpu_priv, i); - if (percpu_priv->dpa_bp_count) - dpa_bp_count = *percpu_priv->dpa_bp_count; + if (dpa_bp->percpu_count) + dpa_bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i)); total.in_interrupt += percpu_priv->in_interrupt; total.stats.rx_packets += percpu_priv->stats.rx_packets; diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c index 6ac088c..d175cdc 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c @@ -529,12 +529,8 @@ static int __cold dpa_eth_priv_start(struct net_device *net_dev) } for_each_online_cpu(i) { percpu_priv = per_cpu_ptr(priv->percpu_priv, i); - if (!percpu_priv->dpa_bp) { + if (!percpu_priv->dpa_bp) percpu_priv->dpa_bp = priv->dpa_bp; - percpu_priv->dpa_bp_count = - per_cpu_ptr(priv->dpa_bp->percpu_count, - i); - } } dpaa_eth_napi_enable(priv); diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h index 900bf11..d19991b 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h @@ -390,12 +390,6 @@ struct dpa_ern_cnt { struct dpa_percpu_priv_s { struct net_device *net_dev; - /* - * Pointer to the percpu_count of the shared buffer pool - * used for the private ports; this assumes there is only - * one bpool used - */ - int *dpa_bp_count; struct dpa_bp *dpa_bp; struct napi_struct napi; u64 in_interrupt; diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c index b7bfc3e..f2c8ced 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c @@ -140,9 +140,9 @@ void dpa_make_private_pool(struct dpa_bp *dpa_bp) */ int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) { - int *countptr = percpu_priv->dpa_bp_count; - int count = *countptr; const struct dpa_bp *dpa_bp = percpu_priv->dpa_bp; + int *countptr = __this_cpu_ptr(dpa_bp->percpu_count); + int count = *countptr; /* this function is called in softirq context; * no need to protect smp_processor_id() on RT kernel */ @@ -256,8 +256,9 @@ static int dpa_process_one(struct dpa_percpu_priv_s *percpu_priv, unsigned long skb_addr = virt_to_phys(skb->head); u32 pad = fd_addr - skb_addr; unsigned int data_start; + int *countptr = __this_cpu_ptr(bp->percpu_count); - (*percpu_priv->dpa_bp_count)--; + (*countptr)--; /* The skb is currently pointed at head + headroom. The packet * starts at skb->head + pad + fd offset. @@ -468,6 +469,7 @@ static int skb_to_contig_fd(struct dpa_priv_s *priv, bool can_recycle = false; int offset, extra_offset; int err; + int *countptr = __this_cpu_ptr(dpa_bp->percpu_count); /* We are guaranteed that we have at least tx_headroom bytes. * Buffers we allocated are padded to improve cache usage. In order @@ -490,7 +492,7 @@ static int skb_to_contig_fd(struct dpa_priv_s *priv, if (likely(skb_is_recycleable(skb, dpa_bp->size) && (skb_end_pointer(skb) - skb->head <= DPA_RECYCLE_MAX_SIZE) && - (*percpu_priv->dpa_bp_count < dpa_bp->target_count))) { + (*countptr < dpa_bp->target_count))) { /* Compute the minimum necessary fd offset */ offset = dpa_bp->size - skb->len - skb_tailroom(skb); @@ -585,6 +587,7 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) struct rtnl_link_stats64 *percpu_stats; int queue_mapping; int err; + int *countptr; /* If there is a Tx hook, run it. */ if (dpaa_eth_hooks.tx && @@ -595,6 +598,7 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) priv = netdev_priv(net_dev); percpu_priv = per_cpu_ptr(priv->percpu_priv, smp_processor_id()); percpu_stats = &percpu_priv->stats; + countptr = __this_cpu_ptr(priv->dpa_bp->percpu_count); clear_fd(&fd); queue_mapping = dpa_get_queue_mapping(skb); @@ -665,7 +669,7 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) */ skb_recycle(skb); skb = NULL; - (*percpu_priv->dpa_bp_count)++; + (*countptr)++; percpu_priv->tx_returned++; } @@ -678,7 +682,7 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) xmit_failed: if (fd.cmd & FM_FD_CMD_FCO) { - (*percpu_priv->dpa_bp_count)--; + (*countptr)--; percpu_priv->tx_returned--; } fd_create_failed: diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c index bc90d29..cffc970 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c @@ -157,9 +157,9 @@ void dpa_make_private_pool(struct dpa_bp *dpa_bp) */ int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv) { - int *countptr = percpu_priv->dpa_bp_count; - int count = *countptr; const struct dpa_bp *dpa_bp = percpu_priv->dpa_bp; + int *countptr = __this_cpu_ptr(percpu_priv->dpa_bp->percpu_count); + int count = *countptr; int new_bufs; /* Add pages to the buffer pool */ @@ -807,11 +807,13 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) int err = 0; const int queue_mapping = dpa_get_queue_mapping(skb); const bool nonlinear = skb_is_nonlinear(skb); + int *countptr; priv = netdev_priv(net_dev); /* Non-migratable context, safe to use __this_cpu_ptr */ percpu_priv = __this_cpu_ptr(priv->percpu_priv); percpu_stats = &percpu_priv->stats; + countptr = __this_cpu_ptr(percpu_priv->dpa_bp->percpu_count); clear_fd(&fd); @@ -891,7 +893,7 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) * of the page containing the recycled buffer to make sure it * doesn't get freed. */ - (*percpu_priv->dpa_bp_count)++; + (*countptr)++; get_page(virt_to_head_page(skb->head)); percpu_priv->tx_returned++; } @@ -909,7 +911,7 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) xmit_failed: if (fd.cmd & FM_FD_CMD_FCO) { - (*percpu_priv->dpa_bp_count)--; + (*countptr)--; put_page(virt_to_head_page(skb->head)); percpu_priv->tx_returned--; } diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_unit_test.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_unit_test.c index 46e8808..5df53a5 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_unit_test.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_unit_test.c @@ -87,6 +87,7 @@ static enum qman_cb_dqrr_result tx_unit_test_dqrr( dma_addr_t addr; unsigned char *startaddr; struct dpa_percpu_priv_s *percpu_priv; + int *countptr; tx_unit_test_passed = false; @@ -126,9 +127,10 @@ static enum qman_cb_dqrr_result tx_unit_test_dqrr( * If we didn't recycle, but the buffer was big enough, * increment the counter to put it back */ + countptr = __this_cpu_ptr(priv->dpa_bp->percpu_count); if (skb_end_pointer(skb) - skb->head >= dpa_get_max_frm()) - (*percpu_priv->dpa_bp_count)++; + (*countptr)++; /* If we didn't recycle, the data pointer should be good */ if (skb->data != startaddr + dpa_fd_offset(fd)) @@ -234,6 +236,8 @@ static int dpa_tx_unit_test(struct net_device *net_dev) headroom += 16) { int ret; struct sk_buff *skb; + int *countptr = + __this_cpu_ptr(priv->dpa_bp->percpu_count); test_count++; @@ -247,7 +251,7 @@ static int dpa_tx_unit_test(struct net_device *net_dev) if (skb_end_pointer(skb) - skb->head >= dpa_get_max_frm()) - (*percpu_priv->dpa_bp_count)--; + (*countptr)--; skb_put(skb, size + headroom); skb_pull(skb, headroom); @@ -368,7 +372,6 @@ void dpa_unit_test_drain_default_pool(struct net_device *net_dev) for_each_online_cpu(i) { percpu_priv = per_cpu_ptr(priv->percpu_priv, i); percpu_priv->dpa_bp = NULL; - percpu_priv->dpa_bp_count = NULL; } } @@ -387,9 +390,6 @@ void dpa_unit_test_seed_default_pool(struct net_device *net_dev) percpu_priv = per_cpu_ptr(priv->percpu_priv, i); if (!percpu_priv->dpa_bp) { percpu_priv->dpa_bp = priv->dpa_bp; - percpu_priv->dpa_bp_count = - per_cpu_ptr(priv->dpa_bp->percpu_count, - i); } } } -- cgit v0.10.2