1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-17 10:26:15 +00:00

When sf_buf_alloc() replaces a virtual-to-physical mapping, it needn't

invalidate the TLB(s) if the old mapping wasn't used by the CPU.  With
network interfaces that implement checksum off-loading, the old mapping is
almost never used by the CPU, only by the device driver for setting up the
DMA operation.

Reviewed by: tegge@
This commit is contained in:
Alan Cox 2004-10-16 22:32:50 +00:00
parent 5e7d6c16fb
commit 20351faf18
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=136601

View File

@ -617,6 +617,7 @@ sf_buf_init(void *arg)
struct sf_buf *
sf_buf_alloc(struct vm_page *m, int pri)
{
pt_entry_t opte, *ptep;
struct sf_head *hash_list;
struct sf_buf *sf;
int error;
@ -655,7 +656,20 @@ sf_buf_alloc(struct vm_page *m, int pri)
sf->m = m;
nsfbufsused++;
nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
pmap_qenter(sf->kva, &sf->m, 1);
/*
* Update the sf_buf's virtual-to-physical mapping, flushing the
* virtual address from the TLB only if the PTE implies that the old
* mapping has been used. Since the reference count for the sf_buf's
* old mapping was zero, that mapping is not currently in use.
* Consequently, there is no need to exchange the old and new PTEs
* atomically, even under PAE.
*/
ptep = vtopte(sf->kva);
opte = *ptep;
*ptep = VM_PAGE_TO_PHYS(m) | pgeflag | PG_RW | PG_V;
if ((opte & (PG_A | PG_V)) == (PG_A | PG_V))
pmap_invalidate_page(kernel_pmap, sf->kva);
done:
mtx_unlock(&sf_buf_lock);
return (sf);