Date: Sat, 9 Sep 2017 05:12:14 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r323343 - head/sys/dev/cxgbe Message-ID: <201709090512.v895CEpW031633@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Sat Sep 9 05:12:14 2017 New Revision: 323343 URL: https://svnweb.freebsd.org/changeset/base/323343 Log: cxgbe(4): Fix a couple of problems in the sge_wrq data path. - start_wrq_wr must not drain the wr_list if there are incomplete_wrs pending. This can happen when a t4_wrq_tx runs between two start_wrq_wr. - commit_wrq_wr must examine the cookie's pidx and ndesc with the queue's lock held. Otherwise there is a bad race when incomplete WRs are being completed and commit_wrq_wr for the WR that is ahead in the queue updates the next incomplete WR's cookie's pidx/ndesc but the commit_wrq_wr for the second one is using stale values that it read without the lock. MFC after: 1 week Sponsored by: Chelsio Communications Modified: head/sys/dev/cxgbe/t4_sge.c Modified: head/sys/dev/cxgbe/t4_sge.c ============================================================================== --- head/sys/dev/cxgbe/t4_sge.c Sat Sep 9 03:09:02 2017 (r323342) +++ head/sys/dev/cxgbe/t4_sge.c Sat Sep 9 05:12:14 2017 (r323343) @@ -2354,7 +2354,7 @@ start_wrq_wr(struct sge_wrq *wrq, int len16, struct wr EQ_LOCK(eq); - if (!STAILQ_EMPTY(&wrq->wr_list)) + if (TAILQ_EMPTY(&wrq->incomplete_wrs) && !STAILQ_EMPTY(&wrq->wr_list)) drain_wrq_wr_list(sc, wrq); if (!STAILQ_EMPTY(&wrq->wr_list)) { @@ -2408,9 +2408,6 @@ commit_wrq_wr(struct sge_wrq *wrq, void *w, struct wrq return; } - ndesc = cookie->ndesc; /* Can be more than SGE_MAX_WR_NDESC here. */ - pidx = cookie->pidx; - MPASS(pidx >= 0 && pidx < eq->sidx); if (__predict_false(w == &wrq->ss[0])) { int n = (eq->sidx - wrq->ss_pidx) * EQ_ESIZE; @@ -2422,6 +2419,9 @@ commit_wrq_wr(struct sge_wrq *wrq, void *w, struct wrq wrq->tx_wrs_direct++; EQ_LOCK(eq); + ndesc = cookie->ndesc; /* Can be more than SGE_MAX_WR_NDESC here. */ + pidx = cookie->pidx; + MPASS(pidx >= 0 && pidx < eq->sidx); prev = TAILQ_PREV(cookie, wrq_incomplete_wrs, link); next = TAILQ_NEXT(cookie, link); if (prev == NULL) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709090512.v895CEpW031633>