Implement support for CPU private mappings within sf_buf_alloc().
This commit is contained in:
parent
3b278dbbfb
commit
5c0db7c71a
@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/pcb_ext.h>
|
||||
#include <machine/smp.h>
|
||||
#include <machine/vm86.h>
|
||||
|
||||
#ifdef CPU_ELAN
|
||||
@ -610,8 +611,13 @@ sf_buf_alloc(struct vm_page *m, int flags)
|
||||
pt_entry_t opte, *ptep;
|
||||
struct sf_head *hash_list;
|
||||
struct sf_buf *sf;
|
||||
#ifdef SMP
|
||||
cpumask_t cpumask, other_cpus;
|
||||
#endif
|
||||
int error;
|
||||
|
||||
KASSERT(curthread->td_pinned > 0 || (flags & SFB_CPUPRIVATE) == 0,
|
||||
("sf_buf_alloc(SFB_CPUPRIVATE): curthread not pinned"));
|
||||
hash_list = &sf_buf_active[SF_BUF_HASH(m)];
|
||||
mtx_lock(&sf_buf_lock);
|
||||
LIST_FOREACH(sf, hash_list, list_entry) {
|
||||
@ -622,6 +628,22 @@ sf_buf_alloc(struct vm_page *m, int flags)
|
||||
nsfbufsused++;
|
||||
nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
|
||||
}
|
||||
#ifdef SMP
|
||||
cpumask = PCPU_GET(cpumask);
|
||||
if ((sf->cpumask & cpumask) == 0) {
|
||||
sf->cpumask |= cpumask;
|
||||
invlpg(sf->kva);
|
||||
}
|
||||
if ((flags & SFB_CPUPRIVATE) == 0) {
|
||||
other_cpus = PCPU_GET(other_cpus) & ~sf->cpumask;
|
||||
if (other_cpus != 0) {
|
||||
sf->cpumask |= other_cpus;
|
||||
mtx_lock_spin(&smp_ipi_mtx);
|
||||
smp_masked_invlpg(other_cpus, sf->kva);
|
||||
mtx_unlock_spin(&smp_ipi_mtx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -660,6 +682,17 @@ sf_buf_alloc(struct vm_page *m, int flags)
|
||||
ptep = vtopte(sf->kva);
|
||||
opte = *ptep;
|
||||
*ptep = VM_PAGE_TO_PHYS(m) | pgeflag | PG_RW | PG_V;
|
||||
#ifdef SMP
|
||||
if (flags & SFB_CPUPRIVATE) {
|
||||
if ((opte & (PG_A | PG_V)) == (PG_A | PG_V)) {
|
||||
sf->cpumask = PCPU_GET(cpumask);
|
||||
invlpg(sf->kva);
|
||||
} else
|
||||
sf->cpumask = all_cpus;
|
||||
goto done;
|
||||
} else
|
||||
sf->cpumask = all_cpus;
|
||||
#endif
|
||||
if ((opte & (PG_A | PG_V)) == (PG_A | PG_V))
|
||||
pmap_invalidate_page(kernel_pmap, sf->kva);
|
||||
done:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu>
|
||||
* Copyright (c) 2003, 2005 Alan L. Cox <alc@cs.rice.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -39,6 +39,9 @@ struct sf_buf {
|
||||
struct vm_page *m; /* currently mapped page */
|
||||
vm_offset_t kva; /* va of mapping */
|
||||
int ref_count; /* usage of this mapping */
|
||||
#ifdef SMP
|
||||
cpumask_t cpumask; /* cpus on which mapping is valid */
|
||||
#endif
|
||||
};
|
||||
|
||||
static __inline vm_offset_t
|
||||
|
Loading…
Reference in New Issue
Block a user