1. 31 Jan, 2018 1 commit
    • bigfile/virtmem: Fix build with recent glibc · c3cc8a99
      It was
      
      	bigfile/pagefault.c:45:36: warning: ‘struct ucontext’ declared inside parameter list will not be visible outside of this definition or declaration
      	 static int faulted_by(const struct ucontext *uc);
      	                                    ^~~~~~~~
      	bigfile/pagefault.c: In function ‘on_pagefault’:
      	bigfile/pagefault.c:59:24: warning: passing argument 1 of ‘faulted_by’ from incompatible pointer type [-Wincompatible-pointer-types]
      	     write = faulted_by(uc);
      	                        ^~
      	bigfile/pagefault.c:45:12: note: expected ‘const struct ucontext *’ but argument is of type ‘struct ucontext *’
      	 static int faulted_by(const struct ucontext *uc);
      	            ^~~~~~~~~~
      	bigfile/pagefault.c: At top level:
      	bigfile/pagefault.c:208:36: warning: ‘struct ucontext’ declared inside parameter list will not be visible outside of this definition or declaration
      	 static int faulted_by(const struct ucontext *uc)
      	                                    ^~~~~~~~
      	bigfile/pagefault.c:208:12: error: conflicting types for ‘faulted_by’
      	 static int faulted_by(const struct ucontext *uc)
      	            ^~~~~~~~~~
      	bigfile/pagefault.c:45:12: note: previous declaration of ‘faulted_by’ was here
      	 static int faulted_by(const struct ucontext *uc);
      	            ^~~~~~~~~~
      	bigfile/pagefault.c: In function ‘faulted_by’:
      	bigfile/pagefault.c:217:15: error: dereferencing pointer to incomplete type ‘const struct ucontext’
      	     write = uc->uc_mcontext.gregs[REG_ERR] & 0x2;
      	               ^~
      	bigfile/pagefault.c: At top level:
      	bigfile/pagefault.c:45:12: warning: ‘faulted_by’ used but never defined
      	 static int faulted_by(const struct ucontext *uc);
      	            ^~~~~~~~~~
      	bigfile/pagefault.c:208:12: warning: ‘faulted_by’ defined but not used [-Wunused-function]
      	 static int faulted_by(const struct ucontext *uc)
      	            ^~~~~~~~~~
      
      Change to using ucontext_t because apparently there is no `struct
      ucontext` anymore (and man for sigaction says 3rd parameter to hander is
      of type `ucontext_t *` - not `struct ucontext *` - cast to `void *`)
      
      Explicitly include <ucontext.h> because we are dereferencing ucontext_t,
      even though today it appears to be included by <signal.h>.
      Kirill Smelkov committed
  2. 24 Oct, 2017 1 commit
    • Relicense to GPLv3+ with wide exception for all Free Software / Open Source proj… · f11386a4
      …ects + Business options.
      
      Nexedi stack is licensed under Free Software licenses with various exceptions
      that cover three business cases:
      
      - Free Software
      - Proprietary Software
      - Rebranding
      
      As long as one intends to develop Free Software based on Nexedi stack, no
      license cost is involved. Developing proprietary software based on Nexedi stack
      may require a proprietary exception license. Rebranding Nexedi stack is
      prohibited unless rebranding license is acquired.
      
      Through this licensing approach, Nexedi expects to encourage Free Software
      development without restrictions and at the same time create a framework for
      proprietary software to contribute to the long term sustainability of the
      Nexedi stack.
      
      Please see https://www.nexedi.com/licensing for details, rationale and options.
      Kirill Smelkov committed
  3. 15 Dec, 2015 1 commit
    • bigfile/virtmem: Do loadblk() with virtmem lock released · f49c11a3
      loadblk() calls are potentially slow and external code that serve the cal can
      take other locks in addition to virtmem lock taken by virtmem subsystem. If
      that "other locks" are also taken before external code calls e.g.
      fileh_invalidate_page() in different codepath a deadlock can happen, e.g.
      
            T1                  T2
      
            page-access         invalidation-from-server received
            V -> loadblk
                                Z   <- ClientStorage.invalidateTransaction()
            Z -> zeo.load
                                V   <- fileh_invalidate_page
      
      The solution to avoid deadlock is to call loadblk() with virtmem lock released
      and upon loadblk() completion recheck virtmem data structures carefully.
      
      To make that happen:
      
      - new page state is introduces:
      
          PAGE_LOADING                (file content loading is  in progress)
      
      - virtmem releases virt_lock before calling loadblk() when serving pagefault
      
      - because loading is now done with virtmem lock released, now:
      
      1. After loading completes we need to recheck fileh/vma data structures
      
         The recheck is done in full - vma_on_pagefault() just asks its driver (see
         VM_RETRY and VM_HANDLED codes) to retry handling the fault completely. This
         should work as the freshly loaded page was just inserted into fileh->pagemap
         and should be found there in the cache on next lookup.
      
         On the other hand this also works correctly, if there was concurrent change
         - e.g. vma was unmapped while we were loading the data - in that case the
         fault will be also processed correctly - but loaded data will stay in
         fileh->pagemap (and if not used will be evicted as not-needed
         eventually by RAM reclaim).
      
      2. Similar to retrying mechanism is used for cases when two threads
         concurrently access the same page and would both try to load corresponding
         block - only one thread issues the actual loadblk() and another waits for load
         to complete with polling and VM_RETRY.
      
      3. To correctly invalidate loading-in-progress pages another new page state
         is introduced:
      
          PAGE_LOADING_INVALIDATED    (file content loading was in progress
                                       while request to invalidate the page came in)
      
         which fileh_invalidate_page() uses to propagate invalidation message to
         loadblk() caller.
      
      4. Blocks loading can now happen in parallel with other block loading and
         other virtmem operations - e.g. invalidation. For such cases tests are added
         to test_thread.py
      
      5. virtmem lock now becomes just regular lock, instead of being previously
         recursive.
      
         For virtmem lock to be recursive was needed for cases, when code under
         loadblk() could trigger other virtmem calls, e.g. due to GC and calling
         another VMA dtor that would want to lock virtmem, but virtmem lock was
         already held.
      
         This is no longer needed.
      
      6. To catch double faults we now cannot use just on static variable
         in_on_pagefault. That variable thus becomes thread-local.
      
      7. Old test in test_thread to "test that access vs access don't overlap" no
         longer holds true - and is thus removed.
      
      /cc @Tyagov, @klaus
      Kirill Smelkov committed
  4. 06 Aug, 2015 1 commit
    • bigfile/virtmem: Big Virtmem lock · d53271b9
      At present several threads running can corrupt internal virtmem
      datastructures (e.g. ram->lru_list, fileh->pagemap, etc).
      
      This can happen even if we have zope instances only with 1 worker thread
      - because there are other "system" thread, and python garbage collection
      can trigger at any thread, so if a virtmem object, e.g. VMA or FileH was
      there sitting at GC queue to be collected, their collection, and thus
      e.g. vma_unmap() and fileh_close() will be called from
      different-from-worker thread.
      
      Because of that virtmem just has to be aware of threads not to allow
      internal datastructure corruption.
      
      On the other hand, the idea of introducing userspace virtual memory
      manager turned out to be not so good from performance and complexity
      point of view, and thus the plan is to try to move it back into the
      kernel. This way it does not make sense to do a well-optimised locking
      implementation for userspace version.
      
      So we do just a simple single "protect-all" big lock for virtmem.
      
      Of a particular note is interaction with Python's GIL - any long-lived
      lock has to be taken with GIL released, because else it can deadlock:
      
          t1  t2
      
          G
          V   G
         !G   V
          G
      
      so we introduce helpers to make sure the GIL is not taken, and to retake
      it back if we were holding it initially.
      
      Those helpers (py_gil_ensure_unlocked / py_gil_retake_if_waslocked) are
      symmetrical opposites to what Python provides to make sure the GIL is
      locked (via PyGILState_Ensure / PyGILState_Release).
      
      Otherwise, the patch is more-or-less straightforward application for
      one-big-lock to protect everything idea.
      Kirill Smelkov committed
  5. 03 Apr, 2015 2 commits
    • bigfile/virtmem: Userspace Virtual Memory Manager · 9a293c2d
      Does similar things to what kernel does - users can mmap file parts into
      address space and access them read/write. The manager will be getting
      invoked by hardware/OS kernel for cases when there is no page loaded for
      read, or when a previousle read-only page is being written to.
      
      Additionally to features provided in kernel, it support to be used to
      store back changes in transactional way (see fileh_dirty_writeout()) and
      potentially use huge pages for mappings (though this is currently TODO)
      Kirill Smelkov committed
    • Low-level pagefault handler · 6f7d4d64
      We hook into SIGSEGV and handle read/write pagefaults this way.
      
      In this patch there goes stub code that only detects faults and
      determines (in arch specific way) whether fault was for read or write
      and there is a TODO to pass that information to higher level.
      
      It also comes with tests to detect we still crash if we access something
      incorrectly, so people could have coredumps and investigate them.
      Kirill Smelkov committed