Date: Thu, 16 Jan 2020 11:09:14 +0000 From: bugzilla-noreply@freebsd.org To: net@FreeBSD.org Subject: [Bug 240608] if_vmx(4): iflib - Panic with INVARIANTS: Memory modified after free (12.1-pre-QA) Message-ID: <bug-240608-7501-GwAgsmjUOb@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-240608-7501@https.bugs.freebsd.org/bugzilla/> References: <bug-240608-7501@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D240608 --- Comment #13 from Andriy Gapon <avg@FreeBSD.org> --- I see one potential problem related to ifl_fragidx. _iflib_fl_refill() has this logic: frag_idx =3D fl->ifl_fragidx; <loop> bit_ffc_at(fl->ifl_rx_bitmap, frag_idx, fl->ifl_size,=20=20= =20=20=20=20=20=20=20=20=20 &frag_idx);=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20 if (frag_idx < 0)=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20 bit_ffc(fl->ifl_rx_bitmap, fl->ifl_size, &frag_idx); bit_set(fl->ifl_rx_bitmap, frag_idx); <end of loop> fl->ifl_fragidx =3D frag_idx; So, ifl_fragidx is used to store the latest set bit in ifl_rx_bitmap. bit_ffc_at() finds the first cleared bit at or after the start position. Typically, that means /after/ as the bit /at/ frag_idx is set. But let's consider this scenario. Somehow the hardware consumes descriptors very fast, faster than they are refilled. Let's say we refilled descriptor= s up to index N, so ifl_fragidx=3DN and ifl_pidx=3DN+1. Let's say the hardware = consumed all descriptors available to it. That means that the whole ifl_rx_bitmap is clear and ifl_cidx=3DN+1. Now we do the next refill and we start searching= from ifl_fragidx. That position is free now, so bit_ffc_at() will return it. At this point ifl_fragidx and ifl_pidx get out of sync. We populate various software resources by frag_idx, but we program the hardware by pidx. For example, we will allocate a cluster at index N, but program its bus address= in a descriptor at index N+1. That will mess up things for a driver that expects that indexes are always advanced linearly. There is a simple solution. Either we should store frag_idx + 1 to ifl_fragidx for the benefit of the n= ext refill or we should call bit_ffc_at() with frag_idx + 1 as a starting posit= ion. --=20 You are receiving this mail because: You are the assignee for the bug. You are on the CC list for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-240608-7501-GwAgsmjUOb>