# HG changeset patch # User Paul Boddie # Date 1678126368 -3600 # Node ID 35dad174d0bbcf7df19e3c4c9463625a839d5363 # Parent f91362d40267df0bc28b076f6409d065ecfefc8b Introduced deallocation of pager/region mapper resources. diff -r f91362d40267 -r 35dad174d0bb libexec/include/exec/external_pager.h --- a/libexec/include/exec/external_pager.h Mon Mar 06 18:30:22 2023 +0100 +++ b/libexec/include/exec/external_pager.h Mon Mar 06 19:12:48 2023 +0100 @@ -23,7 +23,9 @@ #include +#include #include +#include #include #include @@ -38,9 +40,20 @@ public NotificationSupport, public Resource { protected: - l4_cap_idx_t _task, _mapped_task, _parent, _mapped_parent, _pager, _mapped_pager, _ipc_gate; + + /* Resources associated with the created process. */ + + l4_cap_idx_t _task = L4_INVALID_CAP, _mapped_task = L4_INVALID_CAP, + _parent = L4_INVALID_CAP, _mapped_parent = L4_INVALID_CAP, + _pager = L4_INVALID_CAP, _mapped_pager = L4_INVALID_CAP, + _ipc_gate = L4_INVALID_CAP; std::vector _threads, _mapped_threads; + /* Resources supporting the internal pager. */ + + ExplicitSegment *_rm_stack = NULL; + Payload *_rm_payload = NULL; + public: explicit ExternalPager(address_t start = 0, address_t end = 0); @@ -59,6 +72,11 @@ virtual void set_parent(l4_cap_idx_t cap, l4_cap_idx_t mapped_cap); virtual void set_task(l4_cap_idx_t cap, l4_cap_idx_t mapped_cap); + /* Internal pager resource management. */ + + virtual void set_payload(Payload *payload); + virtual void set_stack(ExplicitSegment *stack); + /* Resource methods. */ virtual void close(); diff -r f91362d40267 -r 35dad174d0bb libexec/include/exec/pager.h --- a/libexec/include/exec/pager.h Mon Mar 06 18:30:22 2023 +0100 +++ b/libexec/include/exec/pager.h Mon Mar 06 19:12:48 2023 +0100 @@ -1,7 +1,7 @@ /* * Common system pager functionality. * - * Copyright (C) 2022 Paul Boddie + * Copyright (C) 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -56,6 +56,8 @@ virtual void add(MappedRegion ®ion); + virtual void remove(MappedRegion ®ion); + /* Notification methods. */ virtual long exception(l4_exc_regs_t regs, diff -r f91362d40267 -r 35dad174d0bb libexec/include/exec/segment.h --- a/libexec/include/exec/segment.h Mon Mar 06 18:30:22 2023 +0100 +++ b/libexec/include/exec/segment.h Mon Mar 06 19:12:48 2023 +0100 @@ -99,6 +99,8 @@ +/* An explicitly created segment independent of any particular payload. */ + class ExplicitSegment : public Segment { protected: diff -r f91362d40267 -r 35dad174d0bb libexec/lib/src/external_pager.cc --- a/libexec/lib/src/external_pager.cc Mon Mar 06 18:30:22 2023 +0100 +++ b/libexec/lib/src/external_pager.cc Mon Mar 06 19:12:48 2023 +0100 @@ -60,7 +60,22 @@ { printf("Pager closing...\n"); - /* Unmap all regions. */ + /* Remove pager regions to avoid unmapping them twice. */ + + remove(_rm_stack->region()); + + for (unsigned int i = 0; i < _rm_payload->segments(); i++) + remove(_rm_payload->segment(i)->region()); + + /* Delete the pager resources. */ + + if (_rm_payload != NULL) + delete _rm_payload; + + if (_rm_stack != NULL) + delete _rm_stack; + + /* Unmap all remaining regions. */ MappedRegions::iterator it; @@ -117,6 +132,20 @@ +/* Manage pager resources. */ + +void ExternalPager::set_payload(Payload *payload) +{ + _rm_payload = payload; +} + +void ExternalPager::set_stack(ExplicitSegment *stack) +{ + _rm_stack = stack; +} + + + /* Handle a general exception. */ long ExternalPager::exception(l4_exc_regs_t regs, l4_snd_fpage_t *region) diff -r f91362d40267 -r 35dad174d0bb libexec/lib/src/pager.cc --- a/libexec/lib/src/pager.cc Mon Mar 06 18:30:22 2023 +0100 +++ b/libexec/lib/src/pager.cc Mon Mar 06 19:12:48 2023 +0100 @@ -1,7 +1,7 @@ /* * Common system pager functionality. * - * Copyright (C) 2022 Paul Boddie + * Copyright (C) 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -41,6 +41,8 @@ { } + + /* Add a region to the pager. */ void ExecPager::add(MappedRegion ®ion) @@ -48,6 +50,15 @@ _regions[region.start] = region; } +/* Remove a region from the pager. */ + +void ExecPager::remove(MappedRegion ®ion) +{ + _regions.erase(region.start); +} + + + /* Attach a region for provision when page faults occur. */ long ExecPager::find(address_t *start, address_t *size, map_flags_t flags, diff -r f91362d40267 -r 35dad174d0bb libexec/lib/src/process_creating.cc --- a/libexec/lib/src/process_creating.cc Mon Mar 06 18:30:22 2023 +0100 +++ b/libexec/lib/src/process_creating.cc Mon Mar 06 19:12:48 2023 +0100 @@ -42,8 +42,6 @@ ProcessCreating::ProcessCreating(const char *rm_filename) : _rm_filename(rm_filename) { - _rm_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW); - _program_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size * 2, initial_stack_size, L4_FPAGE_RW); } /* Initialise the memory segments of the region mapper. These are mapped into @@ -57,6 +55,7 @@ if (err) return err; + _rm_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW); return _rm_stack->allocate(true); } @@ -71,6 +70,7 @@ if (err) return err; + _program_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size * 2, initial_stack_size, L4_FPAGE_RW); return _program_stack->allocate(true); } @@ -94,6 +94,8 @@ /* Include the region mapper's stack region. */ _exec_pager->add(_rm_stack->region()); + _exec_pager->set_payload(_rm_payload); + _exec_pager->set_stack(_rm_stack); /* Start the pager in a separate thread. */