Merge branch 'thunderx-fix-receive-buffer-page-recycling'

Dean Nelson says:

====================
thunderx: fix receive buffer page recycling

In attempting to optimize receive buffer page recycling for XDP, commit
773225388d ("net: thunderx: Optimize page recycling for XDP")
inadvertently introduced two problems for the non-XDP case, that will be
addressed by this patch series.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-03-27 22:52:28 -07:00
Родитель 7f07e5f1f7 cd35ef9149
Коммит 23da1021a5
1 изменённых файлов: 14 добавлений и 16 удалений

Просмотреть файл

@ -105,20 +105,19 @@ static inline struct pgcache *nicvf_alloc_page(struct nicvf *nic,
/* Check if page can be recycled */ /* Check if page can be recycled */
if (page) { if (page) {
ref_count = page_ref_count(page); ref_count = page_ref_count(page);
/* Check if this page has been used once i.e 'put_page' /* This page can be recycled if internal ref_count and page's
* called after packet transmission i.e internal ref_count * ref_count are equal, indicating that the page has been used
* and page's ref_count are equal i.e page can be recycled. * once for packet transmission. For non-XDP mode, internal
* ref_count is always '1'.
*/ */
if (rbdr->is_xdp && (ref_count == pgcache->ref_count)) if (rbdr->is_xdp) {
pgcache->ref_count--; if (ref_count == pgcache->ref_count)
else pgcache->ref_count--;
page = NULL; else
page = NULL;
/* In non-XDP mode, page's ref_count needs to be '1' for it } else if (ref_count != 1) {
* to be recycled.
*/
if (!rbdr->is_xdp && (ref_count != 1))
page = NULL; page = NULL;
}
} }
if (!page) { if (!page) {
@ -365,11 +364,10 @@ static void nicvf_free_rbdr(struct nicvf *nic, struct rbdr *rbdr)
while (head < rbdr->pgcnt) { while (head < rbdr->pgcnt) {
pgcache = &rbdr->pgcache[head]; pgcache = &rbdr->pgcache[head];
if (pgcache->page && page_ref_count(pgcache->page) != 0) { if (pgcache->page && page_ref_count(pgcache->page) != 0) {
if (!rbdr->is_xdp) { if (rbdr->is_xdp) {
put_page(pgcache->page); page_ref_sub(pgcache->page,
continue; pgcache->ref_count - 1);
} }
page_ref_sub(pgcache->page, pgcache->ref_count - 1);
put_page(pgcache->page); put_page(pgcache->page);
} }
head++; head++;