Commit befc7a33 authored by David S. Miller's avatar David S. Miller

Merge branch 'nfp-fix-ethtool-stats-and-page-allocation'

Jakub Kicinski says:

====================
nfp: fix ethtool stats and page allocation

Two fixes for net.  First one makes sure we handle gather of stats on
32bit machines correctly (ouch).  The second fix solves a potential
NULL-deref if we fail to allocate a page with XDP running.

I used Fixes: tags pointing to where the bug was introduced, but for
patch 1 it has been in the driver "for ever" and fix won't backport
cleanly beyond commit 325945ed ("nfp: split software and hardware
vNIC statistics") which is in net.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3668bb8d 5f0ca2fb
...@@ -1180,10 +1180,14 @@ static void *nfp_net_rx_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr) ...@@ -1180,10 +1180,14 @@ static void *nfp_net_rx_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr)
{ {
void *frag; void *frag;
if (!dp->xdp_prog) if (!dp->xdp_prog) {
frag = netdev_alloc_frag(dp->fl_bufsz); frag = netdev_alloc_frag(dp->fl_bufsz);
else } else {
frag = page_address(alloc_page(GFP_KERNEL | __GFP_COLD)); struct page *page;
page = alloc_page(GFP_KERNEL | __GFP_COLD);
frag = page ? page_address(page) : NULL;
}
if (!frag) { if (!frag) {
nn_dp_warn(dp, "Failed to alloc receive page frag\n"); nn_dp_warn(dp, "Failed to alloc receive page frag\n");
return NULL; return NULL;
...@@ -1203,10 +1207,14 @@ static void *nfp_net_napi_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr) ...@@ -1203,10 +1207,14 @@ static void *nfp_net_napi_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr)
{ {
void *frag; void *frag;
if (!dp->xdp_prog) if (!dp->xdp_prog) {
frag = napi_alloc_frag(dp->fl_bufsz); frag = napi_alloc_frag(dp->fl_bufsz);
else } else {
frag = page_address(alloc_page(GFP_ATOMIC | __GFP_COLD)); struct page *page;
page = alloc_page(GFP_ATOMIC | __GFP_COLD);
frag = page ? page_address(page) : NULL;
}
if (!frag) { if (!frag) {
nn_dp_warn(dp, "Failed to alloc receive page frag\n"); nn_dp_warn(dp, "Failed to alloc receive page frag\n");
return NULL; return NULL;
......
...@@ -464,7 +464,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) ...@@ -464,7 +464,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
do { do {
start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync); start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync);
*data++ = nn->r_vecs[i].rx_pkts; data[0] = nn->r_vecs[i].rx_pkts;
tmp[0] = nn->r_vecs[i].hw_csum_rx_ok; tmp[0] = nn->r_vecs[i].hw_csum_rx_ok;
tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok; tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok;
tmp[2] = nn->r_vecs[i].hw_csum_rx_error; tmp[2] = nn->r_vecs[i].hw_csum_rx_error;
...@@ -472,14 +472,16 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) ...@@ -472,14 +472,16 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
do { do {
start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync); start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync);
*data++ = nn->r_vecs[i].tx_pkts; data[1] = nn->r_vecs[i].tx_pkts;
*data++ = nn->r_vecs[i].tx_busy; data[2] = nn->r_vecs[i].tx_busy;
tmp[3] = nn->r_vecs[i].hw_csum_tx; tmp[3] = nn->r_vecs[i].hw_csum_tx;
tmp[4] = nn->r_vecs[i].hw_csum_tx_inner; tmp[4] = nn->r_vecs[i].hw_csum_tx_inner;
tmp[5] = nn->r_vecs[i].tx_gather; tmp[5] = nn->r_vecs[i].tx_gather;
tmp[6] = nn->r_vecs[i].tx_lso; tmp[6] = nn->r_vecs[i].tx_lso;
} while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start)); } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start));
data += 3;
for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++) for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++)
gathered_stats[j] += tmp[j]; gathered_stats[j] += tmp[j];
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment