On Thu, 23 May 2019 21:20:35 +0300 Ivan Khoronzhuk <ivan.khoronzhuk@xxxxxxxxxx> wrote: > +static struct page *cpsw_alloc_page(struct cpsw_common *cpsw) > +{ > + struct page_pool *pool = cpsw->rx_page_pool; > + struct page *page, *prev_page = NULL; > + int try = pool->p.pool_size << 2; > + int start_free = 0, ret; > + > + do { > + page = page_pool_dev_alloc_pages(pool); > + if (!page) > + return NULL; > + > + /* if netstack has page_pool recycling remove the rest */ > + if (page_ref_count(page) == 1) > + break; > + > + /* start free pages in use, shouldn't happen */ > + if (prev_page == page || start_free) { > + /* dma unmap/puts page if rfcnt != 1 */ > + page_pool_recycle_direct(pool, page); > + start_free = 1; > + continue; > + } > + > + /* if refcnt > 1, page has been holding by netstack, it's pity, > + * so put it to the ring to be consumed later when fast cash is > + * empty. If ring is full then free page by recycling as above. > + */ > + ret = ptr_ring_produce(&pool->ring, page); This looks very wrong to me! First of all you are manipulation directly with the internal pool->ring and not using the API, which makes this code un-maintainable. Second this is wrong, as page_pool assume the in-variance that pages on the ring have refcnt==1. > + if (ret) { > + page_pool_recycle_direct(pool, page); > + continue; > + } > + > + if (!prev_page) > + prev_page = page; > + } while (try--); > + > + return page; > +} -- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer