[kernel] Remove obsolete 'mappings' list from VMAs
The vm_area_shared type of VMA used to track mappings in a separate array, which doubled information and wasted space. This was no longer used, and is now removed.
This commit is contained in:
@@ -52,145 +52,6 @@ vm_area_shared::~vm_area_shared()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
|
||||||
vm_area_shared::overlaps(uintptr_t offset, size_t pages, size_t *count)
|
|
||||||
{
|
|
||||||
size_t first = 0;
|
|
||||||
size_t n = 0;
|
|
||||||
|
|
||||||
uintptr_t end = offset + pages * frame_size;
|
|
||||||
for (size_t i = 0; i < m_mappings.count(); ++i) {
|
|
||||||
mapping &m = m_mappings[i];
|
|
||||||
uintptr_t map_end = m.offset + m.count * frame_size;
|
|
||||||
if (offset < map_end && end > m.offset) {
|
|
||||||
if (!first) first = i;
|
|
||||||
++n;
|
|
||||||
} else if (n) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count) *count = n;
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
vm_area_shared::commit(uintptr_t phys, uintptr_t offset, size_t count)
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
size_t o = overlaps(offset, count, &n);
|
|
||||||
|
|
||||||
// Mapping overlaps not allowed
|
|
||||||
if (n) return;
|
|
||||||
|
|
||||||
m_mapper.map(offset, count, phys);
|
|
||||||
|
|
||||||
o = m_mappings.sorted_insert({
|
|
||||||
.offset = offset,
|
|
||||||
.count = count,
|
|
||||||
.phys = phys});
|
|
||||||
n = 1;
|
|
||||||
|
|
||||||
// Try to expand to abutting similar areas
|
|
||||||
if (o > 0 &&
|
|
||||||
m_mappings[o-1].end() == offset &&
|
|
||||||
m_mappings[o-1].phys_end() == phys) {
|
|
||||||
--o;
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t end = offset + count * frame_size;
|
|
||||||
uintptr_t pend = phys + count * frame_size;
|
|
||||||
|
|
||||||
if (o + n < m_mappings.count() &&
|
|
||||||
end == m_mappings[o+n].offset &&
|
|
||||||
m_mappings[o-1].phys == pend) {
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use the first overlap block as our new block
|
|
||||||
mapping &first = m_mappings[o];
|
|
||||||
mapping &last = m_mappings[o + n -1];
|
|
||||||
|
|
||||||
if (offset < first.offset)
|
|
||||||
first.offset = offset;
|
|
||||||
|
|
||||||
size_t diff =
|
|
||||||
(end > last.end() ? end : last.end()) -
|
|
||||||
first.offset;
|
|
||||||
|
|
||||||
first.count = memory::page_count(diff);
|
|
||||||
|
|
||||||
if (n > 1)
|
|
||||||
m_mappings.remove_at(o+1, n-1);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
vm_area_shared::uncommit(uintptr_t offset, size_t count)
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
size_t o = overlaps(offset, count, &n);
|
|
||||||
if (!n) return;
|
|
||||||
|
|
||||||
m_mapper.unmap(offset, count);
|
|
||||||
|
|
||||||
mapping *first = &m_mappings[o];
|
|
||||||
mapping *last = &m_mappings[o+n-1];
|
|
||||||
|
|
||||||
uintptr_t end = offset + count * frame_size;
|
|
||||||
|
|
||||||
size_t leading = offset - first->offset;
|
|
||||||
size_t trailing = last->end() - end;
|
|
||||||
|
|
||||||
// if were entirely contained in one, we need to split it
|
|
||||||
if (leading && trailing && n == 1) {
|
|
||||||
size_t i = m_mappings.sorted_insert({
|
|
||||||
.offset = end,
|
|
||||||
.count = trailing / frame_size,
|
|
||||||
});
|
|
||||||
last = &m_mappings[i];
|
|
||||||
trailing = 0;
|
|
||||||
|
|
||||||
first->count -= last->count;
|
|
||||||
last->phys = first->phys + first->count * frame_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leading) {
|
|
||||||
size_t remove_pages = first->count;
|
|
||||||
first->count = leading / frame_size;
|
|
||||||
remove_pages -= first->count;
|
|
||||||
m_mapper.unmap(first->end(), remove_pages);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trailing) {
|
|
||||||
uintptr_t remove_off = last->offset;
|
|
||||||
size_t remove_pages = last->count;
|
|
||||||
last->offset = end;
|
|
||||||
last->count = trailing / frame_size;
|
|
||||||
remove_pages -= last->count;
|
|
||||||
m_mapper.unmap(remove_off, remove_pages);
|
|
||||||
last->phys += remove_pages * frame_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t delete_start = 0;
|
|
||||||
size_t delete_count = 0;
|
|
||||||
for (size_t i = o; i < o+n; ++i) {
|
|
||||||
mapping &m = m_mappings[i];
|
|
||||||
if (offset <= m.offset && end >= m.end()) {
|
|
||||||
if (!delete_count) delete_start = i;
|
|
||||||
++delete_count;
|
|
||||||
m_mapper.unmap(m.offset, m.count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delete_count)
|
|
||||||
m_mappings.remove_at(delete_start, delete_count);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vm_area_open::vm_area_open(size_t size, vm_space &space, vm_flags flags) :
|
vm_area_open::vm_area_open(size_t size, vm_space &space, vm_flags flags) :
|
||||||
m_mapper(*this, space),
|
m_mapper(*this, space),
|
||||||
|
|||||||
@@ -100,28 +100,8 @@ public:
|
|||||||
virtual vm_mapper & mapper() override { return m_mapper; }
|
virtual vm_mapper & mapper() override { return m_mapper; }
|
||||||
virtual const vm_mapper & mapper() const override { return m_mapper; }
|
virtual const vm_mapper & mapper() const override { return m_mapper; }
|
||||||
|
|
||||||
virtual void commit(uintptr_t phys, uintptr_t offset, size_t count) override;
|
|
||||||
virtual void uncommit(uintptr_t offset, size_t count) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vm_mapper_multi m_mapper;
|
vm_mapper_multi m_mapper;
|
||||||
|
|
||||||
struct mapping {
|
|
||||||
uintptr_t offset;
|
|
||||||
size_t count;
|
|
||||||
uintptr_t phys;
|
|
||||||
|
|
||||||
int compare(const struct mapping &o) const {
|
|
||||||
return offset > o.offset ? 1 : offset < o.offset ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uintptr_t end() const { return offset + count * memory::frame_size; }
|
|
||||||
inline uintptr_t phys_end() const { return phys + count * memory::frame_size; }
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t overlaps(uintptr_t offset, size_t pages, size_t *count);
|
|
||||||
|
|
||||||
kutil::vector<mapping> m_mappings;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user