L4Re/departure

Changeset

504:35dad174d0bb
2023-03-06 Paul Boddie raw files shortlog changelog graph Introduced deallocation of pager/region mapper resources.
libexec/include/exec/external_pager.h (file) libexec/include/exec/pager.h (file) libexec/include/exec/segment.h (file) libexec/lib/src/external_pager.cc (file) libexec/lib/src/pager.cc (file) libexec/lib/src/process_creating.cc (file)
     1.1 --- a/libexec/include/exec/external_pager.h	Mon Mar 06 18:30:22 2023 +0100
     1.2 +++ b/libexec/include/exec/external_pager.h	Mon Mar 06 19:12:48 2023 +0100
     1.3 @@ -23,7 +23,9 @@
     1.4  
     1.5  #include <vector>
     1.6  
     1.7 +#include <exec/elf.h>
     1.8  #include <exec/pager.h>
     1.9 +#include <exec/segment.h>
    1.10  #include <fsserver/notification.h>
    1.11  #include <fsserver/resource.h>
    1.12  
    1.13 @@ -38,9 +40,20 @@
    1.14                        public NotificationSupport, public Resource
    1.15  {
    1.16  protected:
    1.17 -  l4_cap_idx_t _task, _mapped_task, _parent, _mapped_parent, _pager, _mapped_pager, _ipc_gate;
    1.18 +
    1.19 +  /* Resources associated with the created process. */
    1.20 +
    1.21 +  l4_cap_idx_t _task = L4_INVALID_CAP, _mapped_task = L4_INVALID_CAP,
    1.22 +               _parent = L4_INVALID_CAP, _mapped_parent = L4_INVALID_CAP,
    1.23 +               _pager = L4_INVALID_CAP, _mapped_pager = L4_INVALID_CAP,
    1.24 +               _ipc_gate = L4_INVALID_CAP;
    1.25    std::vector<l4_cap_idx_t> _threads, _mapped_threads;
    1.26  
    1.27 +  /* Resources supporting the internal pager. */
    1.28 +
    1.29 +  ExplicitSegment *_rm_stack = NULL;
    1.30 +  Payload *_rm_payload = NULL;
    1.31 +
    1.32  public:
    1.33    explicit ExternalPager(address_t start = 0, address_t end = 0);
    1.34  
    1.35 @@ -59,6 +72,11 @@
    1.36    virtual void set_parent(l4_cap_idx_t cap, l4_cap_idx_t mapped_cap);
    1.37    virtual void set_task(l4_cap_idx_t cap, l4_cap_idx_t mapped_cap);
    1.38  
    1.39 +  /* Internal pager resource management. */
    1.40 +
    1.41 +  virtual void set_payload(Payload *payload);
    1.42 +  virtual void set_stack(ExplicitSegment *stack);
    1.43 +
    1.44    /* Resource methods. */
    1.45  
    1.46    virtual void close();
     2.1 --- a/libexec/include/exec/pager.h	Mon Mar 06 18:30:22 2023 +0100
     2.2 +++ b/libexec/include/exec/pager.h	Mon Mar 06 19:12:48 2023 +0100
     2.3 @@ -1,7 +1,7 @@
     2.4  /*
     2.5   * Common system pager functionality.
     2.6   *
     2.7 - * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
     2.8 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
     2.9   *
    2.10   * This program is free software; you can redistribute it and/or
    2.11   * modify it under the terms of the GNU General Public License as
    2.12 @@ -56,6 +56,8 @@
    2.13  
    2.14    virtual void add(MappedRegion &region);
    2.15  
    2.16 +  virtual void remove(MappedRegion &region);
    2.17 +
    2.18    /* Notification methods. */
    2.19  
    2.20    virtual long exception(l4_exc_regs_t regs,
     3.1 --- a/libexec/include/exec/segment.h	Mon Mar 06 18:30:22 2023 +0100
     3.2 +++ b/libexec/include/exec/segment.h	Mon Mar 06 19:12:48 2023 +0100
     3.3 @@ -99,6 +99,8 @@
     3.4  
     3.5  
     3.6  
     3.7 +/* An explicitly created segment independent of any particular payload. */
     3.8 +
     3.9  class ExplicitSegment : public Segment
    3.10  {
    3.11  protected:
     4.1 --- a/libexec/lib/src/external_pager.cc	Mon Mar 06 18:30:22 2023 +0100
     4.2 +++ b/libexec/lib/src/external_pager.cc	Mon Mar 06 19:12:48 2023 +0100
     4.3 @@ -60,7 +60,22 @@
     4.4  {
     4.5    printf("Pager closing...\n");
     4.6  
     4.7 -  /* Unmap all regions. */
     4.8 +  /* Remove pager regions to avoid unmapping them twice. */
     4.9 +
    4.10 +  remove(_rm_stack->region());
    4.11 +
    4.12 +  for (unsigned int i = 0; i < _rm_payload->segments(); i++)
    4.13 +    remove(_rm_payload->segment(i)->region());
    4.14 +
    4.15 +  /* Delete the pager resources. */
    4.16 +
    4.17 +  if (_rm_payload != NULL)
    4.18 +    delete _rm_payload;
    4.19 +
    4.20 +  if (_rm_stack != NULL)
    4.21 +    delete _rm_stack;
    4.22 +
    4.23 +  /* Unmap all remaining regions. */
    4.24  
    4.25    MappedRegions::iterator it;
    4.26  
    4.27 @@ -117,6 +132,20 @@
    4.28  
    4.29  
    4.30  
    4.31 +/* Manage pager resources. */
    4.32 +
    4.33 +void ExternalPager::set_payload(Payload *payload)
    4.34 +{
    4.35 +  _rm_payload = payload;
    4.36 +}
    4.37 +
    4.38 +void ExternalPager::set_stack(ExplicitSegment *stack)
    4.39 +{
    4.40 +  _rm_stack = stack;
    4.41 +}
    4.42 +
    4.43 +
    4.44 +
    4.45  /* Handle a general exception. */
    4.46  
    4.47  long ExternalPager::exception(l4_exc_regs_t regs, l4_snd_fpage_t *region)
     5.1 --- a/libexec/lib/src/pager.cc	Mon Mar 06 18:30:22 2023 +0100
     5.2 +++ b/libexec/lib/src/pager.cc	Mon Mar 06 19:12:48 2023 +0100
     5.3 @@ -1,7 +1,7 @@
     5.4  /*
     5.5   * Common system pager functionality.
     5.6   *
     5.7 - * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
     5.8 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
     5.9   *
    5.10   * This program is free software; you can redistribute it and/or
    5.11   * modify it under the terms of the GNU General Public License as
    5.12 @@ -41,6 +41,8 @@
    5.13  {
    5.14  }
    5.15  
    5.16 +
    5.17 +
    5.18  /* Add a region to the pager. */
    5.19  
    5.20  void ExecPager::add(MappedRegion &region)
    5.21 @@ -48,6 +50,15 @@
    5.22    _regions[region.start] = region;
    5.23  }
    5.24  
    5.25 +/* Remove a region from the pager. */
    5.26 +
    5.27 +void ExecPager::remove(MappedRegion &region)
    5.28 +{
    5.29 +  _regions.erase(region.start);
    5.30 +}
    5.31 +
    5.32 +
    5.33 +
    5.34  /* Attach a region for provision when page faults occur. */
    5.35  
    5.36  long ExecPager::find(address_t *start, address_t *size, map_flags_t flags,
     6.1 --- a/libexec/lib/src/process_creating.cc	Mon Mar 06 18:30:22 2023 +0100
     6.2 +++ b/libexec/lib/src/process_creating.cc	Mon Mar 06 19:12:48 2023 +0100
     6.3 @@ -42,8 +42,6 @@
     6.4  ProcessCreating::ProcessCreating(const char *rm_filename)
     6.5  : _rm_filename(rm_filename)
     6.6  {
     6.7 -  _rm_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW);
     6.8 -  _program_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size * 2, initial_stack_size, L4_FPAGE_RW);
     6.9  }
    6.10  
    6.11  /* Initialise the memory segments of the region mapper. These are mapped into
    6.12 @@ -57,6 +55,7 @@
    6.13    if (err)
    6.14      return err;
    6.15  
    6.16 +  _rm_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW);
    6.17    return _rm_stack->allocate(true);
    6.18  }
    6.19  
    6.20 @@ -71,6 +70,7 @@
    6.21    if (err)
    6.22      return err;
    6.23  
    6.24 +  _program_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size * 2, initial_stack_size, L4_FPAGE_RW);
    6.25    return _program_stack->allocate(true);
    6.26  }
    6.27  
    6.28 @@ -94,6 +94,8 @@
    6.29    /* Include the region mapper's stack region. */
    6.30  
    6.31    _exec_pager->add(_rm_stack->region());
    6.32 +  _exec_pager->set_payload(_rm_payload);
    6.33 +  _exec_pager->set_stack(_rm_stack);
    6.34  
    6.35    /* Start the pager in a separate thread. */
    6.36