Author: delphij
Date: Thu Feb  6 07:45:07 2020
New Revision: 357608
URL: https://svnweb.freebsd.org/changeset/base/357608

Log:
  Apply a reduced version of upstream 353970510895f6a80adfe60cf71b70a95adfa8bc
  which implements memory limit in xz(1) when running in 32-bit mode.
  
  The change is applied directly in vendor area to ease future import.

Modified:
  vendor/xz/dist/src/xz/hardware.c
  vendor/xz/dist/src/xz/xz.1

Modified: vendor/xz/dist/src/xz/hardware.c
==============================================================================
--- vendor/xz/dist/src/xz/hardware.c    Thu Feb  6 01:25:30 2020        
(r357607)
+++ vendor/xz/dist/src/xz/hardware.c    Thu Feb  6 07:45:07 2020        
(r357608)
@@ -68,8 +68,38 @@ hardware_memlimit_set(uint64_t new_memlimit,
                new_memlimit = (uint32_t)new_memlimit * total_ram / 100;
        }
 
-       if (set_compress)
+       if (set_compress) {
                memlimit_compress = new_memlimit;
+
+#if SIZE_MAX == UINT32_MAX
+               // FIXME?
+               //
+               // When running a 32-bit xz on a system with a lot of RAM and
+               // using a percentage-based memory limit, the result can be
+               // bigger than the 32-bit address space. Limiting the limit
+               // below SIZE_MAX for compression (not decompression) makes
+               // xz lower the compression settings (or number of threads)
+               // to a level that *might* work. In practice it has worked
+               // when using a 64-bit kernel that gives full 4 GiB address
+               // space to 32-bit programs. In other situations this might
+               // still be too high, like 32-bit kernels that may give much
+               // less than 4 GiB to a single application.
+               //
+               // So this is an ugly hack but I will keep it here while
+               // it does more good than bad.
+               //
+               // Use a value less than SIZE_MAX so that there's some room
+               // for the xz program and so on. Don't use 4000 MiB because
+               // it could look like someone mixed up base-2 and base-10.
+               const uint64_t limit_max = UINT64_C(4020) << 20;
+
+               // UINT64_MAX is a special case for the string "max" so
+               // that has to be handled specially.
+               if (memlimit_compress != UINT64_MAX
+                               && memlimit_compress > limit_max)
+                       memlimit_compress = limit_max;
+#endif
+       }
 
        if (set_decompress)
                memlimit_decompress = new_memlimit;

Modified: vendor/xz/dist/src/xz/xz.1
==============================================================================
--- vendor/xz/dist/src/xz/xz.1  Thu Feb  6 01:25:30 2020        (r357607)
+++ vendor/xz/dist/src/xz/xz.1  Thu Feb  6 07:45:07 2020        (r357608)
@@ -1005,6 +1005,25 @@ instead of
 until the details have been decided.
 .RE
 .IP ""
+For 32-bit
+.BR xz
+there is a special case: if the
+.I limit
+would be over
+.BR "4020\ MiB" ,
+the
+.I limit
+is set to
+.BR "4020\ MiB" .
+(The values
+.B 0
+and
+.B max
+aren't affected by this.
+A similar feature doesn't exist for decompression.)
+This can be helpful when a 32-bit executable has access
+to 4\ GiB address space while hopefully doing no harm in other situations.
+.IP ""
 See also the section
 .BR "Memory usage" .
 .TP
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to