Pull updates from Andrew Morton: "Most of -mm and quite a number of other subsystems: hotfixes, scripts, ocfs2, misc, lib, binfmt, init, reiserfs, exec, dma-mapping, kcov. MM is fairly quiet this time. Holidays, I assume" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (118 commits) kcov: ignore fault-inject and stacktrace include/linux/io-mapping.h-mapping: use PHYS_PFN() macro in io_mapping_map_atomic_wc() execve: warn if process starts with executable stack reiserfs: prevent NULL pointer dereference in reiserfs_insert_item() init/main.c: fix misleading "This architecture does not have kernel memory protection" message init/main.c: fix quoted value handling in unknown_bootoption init/main.c: remove unnecessary repair_env_string in do_initcall_level init/main.c: log arguments and environment passed to init fs/binfmt_elf.c: coredump: allow process with empty address space to coredump fs/binfmt_elf.c: coredump: delete duplicated overflow check fs/binfmt_elf.c: coredump: allocate core ELF header on stack fs/binfmt_elf.c: make BAD_ADDR() unlikely fs/binfmt_elf.c: better codegen around current->mm fs/binfmt_elf.c: don't copy ELF header around fs/binfmt_elf.c: fix ->start_code calculation fs/binfmt_elf.c: smaller code generation around auxv vector fill lib/find_bit.c: uninline helper _find_next_bit() lib/find_bit.c: join _find_next_bit{_le} uapi: rename ext2_swab() to swab() and share globally in swab.h lib/scatterlist.c: adjust indentation in __sg_alloc_table ...
Unified · Split
| @@ -834,6 +834,18 @@ · 833 unmodified lines | ||
| 834 | 834 | dump out devices still on the deferred probe list after |
| 835 | 835 | retrying. |
| 836 | 836 | |
| 837 | + dfltcc= [HW,S390] | |
| 838 | + Format: { on | off | def_only | inf_only | always } | |
| 839 | + on: s390 zlib hardware support for compression on | |
| 840 | + level 1 and decompression (default) | |
| 841 | + off: No s390 zlib hardware support | |
| 842 | + def_only: s390 zlib hardware support for deflate | |
| 843 | + only (compression on level 1) | |
| 844 | + inf_only: s390 zlib hardware support for inflate | |
| 845 | + only (decompression) | |
| 846 | + always: Same as 'on' but ignores the selected compression | |
| 847 | + level always using hardware support (used for debugging) | |
| 848 | + | |
| 837 | 849 | dhash_entries= [KNL] |
| 838 | 850 | Set number of hash buckets for dentry cache. |
| 839 | 851 | |
| @@ -31,6 +31,7 @@ Core utilities · 30 unmodified lines | ||
| 31 | 31 | generic-radix-tree |
| 32 | 32 | memory-allocation |
| 33 | 33 | mm-api |
| 34 | + pin_user_pages | |
| 34 | 35 | gfp_mask-from-fs-io |
| 35 | 36 | timekeeping |
| 36 | 37 | boot-time-mm |
| @@ -0,0 +1,232 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +==================================================== | |
| 4 | +pin_user_pages() and related calls | |
| 5 | +==================================================== | |
| 6 | + | |
| 7 | +.. contents:: :local: | |
| 8 | + | |
| 9 | +Overview | |
| 10 | +======== | |
| 11 | + | |
| 12 | +This document describes the following functions:: | |
| 13 | + | |
| 14 | + pin_user_pages() | |
| 15 | + pin_user_pages_fast() | |
| 16 | + pin_user_pages_remote() | |
| 17 | + | |
| 18 | +Basic description of FOLL_PIN | |
| 19 | +============================= | |
| 20 | + | |
| 21 | +FOLL_PIN and FOLL_LONGTERM are flags that can be passed to the get_user_pages*() | |
| 22 | +("gup") family of functions. FOLL_PIN has significant interactions and | |
| 23 | +interdependencies with FOLL_LONGTERM, so both are covered here. | |
| 24 | + | |
| 25 | +FOLL_PIN is internal to gup, meaning that it should not appear at the gup call | |
| 26 | +sites. This allows the associated wrapper functions (pin_user_pages*() and | |
| 27 | +others) to set the correct combination of these flags, and to check for problems | |
| 28 | +as well. | |
| 29 | + | |
| 30 | +FOLL_LONGTERM, on the other hand, *is* allowed to be set at the gup call sites. | |
| 31 | +This is in order to avoid creating a large number of wrapper functions to cover | |
| 32 | +all combinations of get*(), pin*(), FOLL_LONGTERM, and more. Also, the | |
| 33 | +pin_user_pages*() APIs are clearly distinct from the get_user_pages*() APIs, so | |
| 34 | +that's a natural dividing line, and a good point to make separate wrapper calls. | |
| 35 | +In other words, use pin_user_pages*() for DMA-pinned pages, and | |
| 36 | +get_user_pages*() for other cases. There are four cases described later on in | |
| 37 | +this document, to further clarify that concept. | |
| 38 | + | |
| 39 | +FOLL_PIN and FOLL_GET are mutually exclusive for a given gup call. However, | |
| 40 | +multiple threads and call sites are free to pin the same struct pages, via both | |
| 41 | +FOLL_PIN and FOLL_GET. It's just the call site that needs to choose one or the | |
| 42 | +other, not the struct page(s). | |
| 43 | + | |
| 44 | +The FOLL_PIN implementation is nearly the same as FOLL_GET, except that FOLL_PIN | |
| 45 | +uses a different reference counting technique. | |
| 46 | + | |
| 47 | +FOLL_PIN is a prerequisite to FOLL_LONGTERM. Another way of saying that is, | |
| 48 | +FOLL_LONGTERM is a specific case, more restrictive case of FOLL_PIN. | |
| 49 | + | |
| 50 | +Which flags are set by each wrapper | |
| 51 | +=================================== | |
| 52 | + | |
| 53 | +For these pin_user_pages*() functions, FOLL_PIN is OR'd in with whatever gup | |
| 54 | +flags the caller provides. The caller is required to pass in a non-null struct | |
| 55 | +pages* array, and the function then pin pages by incrementing each by a special | |
| 56 | +value. For now, that value is +1, just like get_user_pages*().:: | |
| 57 | + | |
| 58 | + Function | |
| 59 | + -------- | |
| 60 | + pin_user_pages FOLL_PIN is always set internally by this function. | |
| 61 | + pin_user_pages_fast FOLL_PIN is always set internally by this function. | |
| 62 | + pin_user_pages_remote FOLL_PIN is always set internally by this function. | |
| 63 | + | |
| 64 | +For these get_user_pages*() functions, FOLL_GET might not even be specified. | |
| 65 | +Behavior is a little more complex than above. If FOLL_GET was *not* specified, | |
| 66 | +but the caller passed in a non-null struct pages* array, then the function | |
| 67 | +sets FOLL_GET for you, and proceeds to pin pages by incrementing the refcount | |
| 68 | +of each page by +1.:: | |
| 69 | + | |
| 70 | + Function | |
| 71 | + -------- | |
| 72 | + get_user_pages FOLL_GET is sometimes set internally by this function. | |
| 73 | + get_user_pages_fast FOLL_GET is sometimes set internally by this function. | |
| 74 | + get_user_pages_remote FOLL_GET is sometimes set internally by this function. | |
| 75 | + | |
| 76 | +Tracking dma-pinned pages | |
| 77 | +========================= | |
| 78 | + | |
| 79 | +Some of the key design constraints, and solutions, for tracking dma-pinned | |
| 80 | +pages: | |
| 81 | + | |
| 82 | +* An actual reference count, per struct page, is required. This is because | |
| 83 | + multiple processes may pin and unpin a page. | |
| 84 | + | |
| 85 | +* False positives (reporting that a page is dma-pinned, when in fact it is not) | |
| 86 | + are acceptable, but false negatives are not. | |
| 87 | + | |
| 88 | +* struct page may not be increased in size for this, and all fields are already | |
| 89 | + used. | |
| 90 | + | |
| 91 | +* Given the above, we can overload the page->_refcount field by using, sort of, | |
| 92 | + the upper bits in that field for a dma-pinned count. "Sort of", means that, | |
| 93 | + rather than dividing page->_refcount into bit fields, we simple add a medium- | |
| 94 | + large value (GUP_PIN_COUNTING_BIAS, initially chosen to be 1024: 10 bits) to | |
| 95 | + page->_refcount. This provides fuzzy behavior: if a page has get_page() called | |
| 96 | + on it 1024 times, then it will appear to have a single dma-pinned count. | |
| 97 | + And again, that's acceptable. | |
| 98 | + | |
| 99 | +This also leads to limitations: there are only 31-10==21 bits available for a | |
| 100 | +counter that increments 10 bits at a time. | |
| 101 | + | |
| 102 | +TODO: for 1GB and larger huge pages, this is cutting it close. That's because | |
| 103 | +when pin_user_pages() follows such pages, it increments the head page by "1" | |
| 104 | +(where "1" used to mean "+1" for get_user_pages(), but now means "+1024" for | |
| 105 | +pin_user_pages()) for each tail page. So if you have a 1GB huge page: | |
| 106 | + | |
| 107 | +* There are 256K (18 bits) worth of 4 KB tail pages. | |
| 108 | +* There are 21 bits available to count up via GUP_PIN_COUNTING_BIAS (that is, | |
| 109 | + 10 bits at a time) | |
| 110 | +* There are 21 - 18 == 3 bits available to count. Except that there aren't, | |
| 111 | + because you need to allow for a few normal get_page() calls on the head page, | |
| 112 | + as well. Fortunately, the approach of using addition, rather than "hard" | |
| 113 | + bitfields, within page->_refcount, allows for sharing these bits gracefully. | |
| 114 | + But we're still looking at about 8 references. | |
| 115 | + | |
| 116 | +This, however, is a missing feature more than anything else, because it's easily | |
| 117 | +solved by addressing an obvious inefficiency in the original get_user_pages() | |
| 118 | +approach of retrieving pages: stop treating all the pages as if they were | |
| 119 | +PAGE_SIZE. Retrieve huge pages as huge pages. The callers need to be aware of | |
| 120 | +this, so some work is required. Once that's in place, this limitation mostly | |
| 121 | +disappears from view, because there will be ample refcounting range available. | |
| 122 | + | |
| 123 | +* Callers must specifically request "dma-pinned tracking of pages". In other | |
| 124 | + words, just calling get_user_pages() will not suffice; a new set of functions, | |
| 125 | + pin_user_page() and related, must be used. | |
| 126 | + | |
| 127 | +FOLL_PIN, FOLL_GET, FOLL_LONGTERM: when to use which flags | |
| 128 | +========================================================== | |
| 129 | + | |
| 130 | +Thanks to Jan Kara, Vlastimil Babka and several other -mm people, for describing | |
| 131 | +these categories: | |
| 132 | + | |
| 133 | +CASE 1: Direct IO (DIO) | |
| 134 | +----------------------- | |
| 135 | +There are GUP references to pages that are serving | |
| 136 | +as DIO buffers. These buffers are needed for a relatively short time (so they | |
| 137 | +are not "long term"). No special synchronization with page_mkclean() or | |
| 138 | +munmap() is provided. Therefore, flags to set at the call site are: :: | |
| 139 | + | |
| 140 | + FOLL_PIN | |
| 141 | + | |
| 142 | +...but rather than setting FOLL_PIN directly, call sites should use one of | |
| 143 | +the pin_user_pages*() routines that set FOLL_PIN. | |
| 144 | + | |
| 145 | +CASE 2: RDMA | |
| 146 | +------------ | |
| 147 | +There are GUP references to pages that are serving as DMA | |
| 148 | +buffers. These buffers are needed for a long time ("long term"). No special | |
| 149 | +synchronization with page_mkclean() or munmap() is provided. Therefore, flags | |
| 150 | +to set at the call site are: :: | |
| 151 | + | |
| 152 | + FOLL_PIN | FOLL_LONGTERM | |
| 153 | + | |
| 154 | +NOTE: Some pages, such as DAX pages, cannot be pinned with longterm pins. That's | |
| 155 | +because DAX pages do not have a separate page cache, and so "pinning" implies | |
| 156 | +locking down file system blocks, which is not (yet) supported in that way. | |
| 157 | + | |
| 158 | +CASE 3: Hardware with page faulting support | |
| 159 | +------------------------------------------- | |
| 160 | +Here, a well-written driver doesn't normally need to pin pages at all. However, | |
| 161 | +if the driver does choose to do so, it can register MMU notifiers for the range, | |
| 162 | +and will be called back upon invalidation. Either way (avoiding page pinning, or | |
| 163 | +using MMU notifiers to unpin upon request), there is proper synchronization with | |
| 164 | +both filesystem and mm (page_mkclean(), munmap(), etc). | |
| 165 | + | |
| 166 | +Therefore, neither flag needs to be set. | |
| 167 | + | |
| 168 | +In this case, ideally, neither get_user_pages() nor pin_user_pages() should be | |
| 169 | +called. Instead, the software should be written so that it does not pin pages. | |
| 170 | +This allows mm and filesystems to operate more efficiently and reliably. | |
| 171 | + | |
| 172 | +CASE 4: Pinning for struct page manipulation only | |
| 173 | +------------------------------------------------- | |
| 174 | +Here, normal GUP calls are sufficient, so neither flag needs to be set. | |
| 175 | + | |
| 176 | +page_dma_pinned(): the whole point of pinning | |
| 177 | +============================================= | |
| 178 | + | |
| 179 | +The whole point of marking pages as "DMA-pinned" or "gup-pinned" is to be able | |
| 180 | +to query, "is this page DMA-pinned?" That allows code such as page_mkclean() | |
| 181 | +(and file system writeback code in general) to make informed decisions about | |
| 182 | +what to do when a page cannot be unmapped due to such pins. | |
| 183 | + | |
| 184 | +What to do in those cases is the subject of a years-long series of discussions | |
| 185 | +and debates (see the References at the end of this document). It's a TODO item | |
| 186 | +here: fill in the details once that's worked out. Meanwhile, it's safe to say | |
| 187 | +that having this available: :: | |
| 188 | + | |
| 189 | + static inline bool page_dma_pinned(struct page *page) | |
| 190 | + | |
| 191 | +...is a prerequisite to solving the long-running gup+DMA problem. | |
| 192 | + | |
| 193 | +Another way of thinking about FOLL_GET, FOLL_PIN, and FOLL_LONGTERM | |
| 194 | +=================================================================== | |
| 195 | + | |
| 196 | +Another way of thinking about these flags is as a progression of restrictions: | |
| 197 | +FOLL_GET is for struct page manipulation, without affecting the data that the | |
| 198 | +struct page refers to. FOLL_PIN is a *replacement* for FOLL_GET, and is for | |
| 199 | +short term pins on pages whose data *will* get accessed. As such, FOLL_PIN is | |
| 200 | +a "more severe" form of pinning. And finally, FOLL_LONGTERM is an even more | |
| 201 | +restrictive case that has FOLL_PIN as a prerequisite: this is for pages that | |
| 202 | +will be pinned longterm, and whose data will be accessed. | |
| 203 | + | |
| 204 | +Unit testing | |
| 205 | +============ | |
| 206 | +This file:: | |
| 207 | + | |
| 208 | + tools/testing/selftests/vm/gup_benchmark.c | |
| 209 | + | |
| 210 | +has the following new calls to exercise the new pin*() wrapper functions: | |
| 211 | + | |
| 212 | +* PIN_FAST_BENCHMARK (./gup_benchmark -a) | |
| 213 | +* PIN_BENCHMARK (./gup_benchmark -b) | |
| 214 | + | |
| 215 | +You can monitor how many total dma-pinned pages have been acquired and released | |
| 216 | +since the system was booted, via two new /proc/vmstat entries: :: | |
| 217 | + | |
| 218 | + /proc/vmstat/nr_foll_pin_requested | |
| 219 | + /proc/vmstat/nr_foll_pin_requested | |
| 220 | + | |
| 221 | +Those are both going to show zero, unless CONFIG_DEBUG_VM is set. This is | |
| 222 | +because there is a noticeable performance drop in unpin_user_page(), when they | |
| 223 | +are activated. | |
| 224 | + | |
| 225 | +References | |
| 226 | +========== | |
| 227 | + | |
| 228 | +* `Some slow progress on get_user_pages() (Apr 2, 2019) <https://lwn.net/Articles/784574/>`_ | |
| 229 | +* `DMA and get_user_pages() (LPC: Dec 12, 2018) <https://lwn.net/Articles/774411/>`_ | |
| 230 | +* `The trouble with get_user_pages() (Apr 30, 2018) <https://lwn.net/Articles/753027/>`_ | |
| 231 | + | |
| 232 | +John Hubbard, October, 2019 | |
| @@ -130,6 +130,19 @@ checking for the same-value filled pages during store operation. However, the · 129 unmodified lines | ||
| 130 | 130 | existing pages which are marked as same-value filled pages remain stored |
| 131 | 131 | unchanged in zswap until they are either loaded or invalidated. |
| 132 | 132 | |
| 133 | +To prevent zswap from shrinking pool when zswap is full and there's a high | |
| 134 | +pressure on swap (this will result in flipping pages in and out zswap pool | |
| 135 | +without any real benefit but with a performance drop for the system), a | |
| 136 | +special parameter has been introduced to implement a sort of hysteresis to | |
| 137 | +refuse taking pages into zswap pool until it has sufficient space if the limit | |
| 138 | +has been hit. To set the threshold at which zswap would start accepting pages | |
| 139 | +again after it became full, use the sysfs ``accept_threhsold_percent`` | |
| 140 | +attribute, e. g.:: | |
| 141 | + | |
| 142 | + echo 80 > /sys/module/zswap/parameters/accept_threhsold_percent | |
| 143 | + | |
| 144 | +Setting this parameter to 100 will disable the hysteresis. | |
| 145 | + | |
| 133 | 146 | A debugfs interface is provided for various statistic about pool size, number |
| 134 | 147 | of pages stored, same-value filled pages and various counters for the reasons |
| 135 | 148 | pages are rejected. |
| @@ -103,7 +103,7 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua, · 102 unmodified lines | ||
| 103 | 103 | for (entry = 0; entry < entries; entry += chunk) { |
| 104 | 104 | unsigned long n = min(entries - entry, chunk); |
| 105 | 105 | |
| 106 | − ret = get_user_pages(ua + (entry << PAGE_SHIFT), n, | |
| 106 | + ret = pin_user_pages(ua + (entry << PAGE_SHIFT), n, | |
| 107 | 107 | FOLL_WRITE | FOLL_LONGTERM, |
| 108 | 108 | mem->hpages + entry, NULL); |
| 109 | 109 | if (ret == n) { |
| @@ -167,9 +167,8 @@ good_exit: · 57 unmodified lines | ||
| 167 | 167 | return 0; |
| 168 | 168 | |
| 169 | 169 | free_exit: |
| 170 | − /* free the reference taken */ | |
| 171 | − for (i = 0; i < pinned; i++) | |
| 172 | − put_page(mem->hpages[i]); | |
| 170 | + /* free the references taken */ | |
| 171 | + unpin_user_pages(mem->hpages, pinned); | |
| 173 | 172 | |
| 174 | 173 | vfree(mem->hpas); |
| 175 | 174 | kfree(mem); |
| @@ -215,7 +214,8 @@ static void mm_iommu_unpin(struct mm_iommu_table_group_mem_t *mem) · 39 unmodified lines | ||
| 215 | 214 | if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY) |
| 216 | 215 | SetPageDirty(page); |
| 217 | 216 | |
| 218 | − put_page(page); | |
| 217 | + unpin_user_page(page); | |
| 218 | + | |
| 219 | 219 | mem->hpas[i] = 0; |
| 220 | 220 | } |
| 221 | 221 | } |
| @@ -30,13 +30,13 @@ extern unsigned char _compressed_start[]; · 29 unmodified lines | ||
| 30 | 30 | extern unsigned char _compressed_end[]; |
| 31 | 31 | |
| 32 | 32 | #ifdef CONFIG_HAVE_KERNEL_BZIP2 |
| 33 | −#define HEAP_SIZE 0x400000 | |
| 33 | +#define BOOT_HEAP_SIZE 0x400000 | |
| 34 | 34 | #else |
| 35 | −#define HEAP_SIZE 0x10000 | |
| 35 | +#define BOOT_HEAP_SIZE 0x10000 | |
| 36 | 36 | #endif |
| 37 | 37 | |
| 38 | 38 | static unsigned long free_mem_ptr = (unsigned long) _end; |
| 39 | −static unsigned long free_mem_end_ptr = (unsigned long) _end + HEAP_SIZE; | |
| 39 | +static unsigned long free_mem_end_ptr = (unsigned long) _end + BOOT_HEAP_SIZE; | |
| 40 | 40 | |
| 41 | 41 | #ifdef CONFIG_KERNEL_GZIP |
| 42 | 42 | #include "../../../../lib/decompress_inflate.c" |
| @@ -62,7 +62,7 @@ static unsigned long free_mem_end_ptr = (unsigned long) _end + HEAP_SIZE; · 19 unmodified lines | ||
| 62 | 62 | #include "../../../../lib/decompress_unxz.c" |
| 63 | 63 | #endif |
| 64 | 64 | |
| 65 | −#define decompress_offset ALIGN((unsigned long)_end + HEAP_SIZE, PAGE_SIZE) | |
| 65 | +#define decompress_offset ALIGN((unsigned long)_end + BOOT_HEAP_SIZE, PAGE_SIZE) | |
| 66 | 66 | |
| 67 | 67 | unsigned long mem_safe_offset(void) |
| 68 | 68 | { |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; |
| 15 | 15 | struct ipl_parameter_block __bootdata_preserved(ipl_block); |
| 16 | 16 | int __bootdata_preserved(ipl_block_valid); |
| 17 | +unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL; | |
| 17 | 18 | |
| 18 | 19 | unsigned long __bootdata(vmalloc_size) = VMALLOC_DEFAULT_SIZE; |
| 19 | 20 | unsigned long __bootdata(memory_end); |
| @@ -229,6 +230,19 @@ void parse_boot_command_line(void) · 209 unmodified lines | ||
| 229 | 230 | if (!strcmp(param, "vmalloc") && val) |
| 230 | 231 | vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE); |
| 231 | 232 | |
| 233 | + if (!strcmp(param, "dfltcc")) { | |
| 234 | + if (!strcmp(val, "off")) | |
| 235 | + zlib_dfltcc_support = ZLIB_DFLTCC_DISABLED; | |
| 236 | + else if (!strcmp(val, "on")) | |
| 237 | + zlib_dfltcc_support = ZLIB_DFLTCC_FULL; | |
| 238 | + else if (!strcmp(val, "def_only")) | |
| 239 | + zlib_dfltcc_support = ZLIB_DFLTCC_DEFLATE_ONLY; | |
| 240 | + else if (!strcmp(val, "inf_only")) | |
| 241 | + zlib_dfltcc_support = ZLIB_DFLTCC_INFLATE_ONLY; | |
| 242 | + else if (!strcmp(val, "always")) | |
| 243 | + zlib_dfltcc_support = ZLIB_DFLTCC_FULL_DEBUG; | |
| 244 | + } | |
| 245 | + | |
| 232 | 246 | if (!strcmp(param, "noexec")) { |
| 233 | 247 | rc = kstrtobool(val, &enabled); |
| 234 | 248 | if (!rc && !enabled) |
| @@ -79,6 +79,13 @@ struct parmarea { · 78 unmodified lines | ||
| 79 | 79 | char command_line[ARCH_COMMAND_LINE_SIZE]; /* 0x10480 */ |
| 80 | 80 | }; |
| 81 | 81 | |
| 82 | +extern unsigned int zlib_dfltcc_support; | |
| 83 | +#define ZLIB_DFLTCC_DISABLED 0 | |
| 84 | +#define ZLIB_DFLTCC_FULL 1 | |
| 85 | +#define ZLIB_DFLTCC_DEFLATE_ONLY 2 | |
| 86 | +#define ZLIB_DFLTCC_INFLATE_ONLY 3 | |
| 87 | +#define ZLIB_DFLTCC_FULL_DEBUG 4 | |
| 88 | + | |
| 82 | 89 | extern int noexec_disabled; |
| 83 | 90 | extern int memory_end_set; |
| 84 | 91 | extern unsigned long memory_end; |
| @@ -111,6 +111,8 @@ unsigned long __bootdata_preserved(__etext_dma); · 110 unmodified lines | ||
| 111 | 111 | unsigned long __bootdata_preserved(__sdma); |
| 112 | 112 | unsigned long __bootdata_preserved(__edma); |
| 113 | 113 | unsigned long __bootdata_preserved(__kaslr_offset); |
| 114 | +unsigned int __bootdata_preserved(zlib_dfltcc_support); | |
| 115 | +EXPORT_SYMBOL(zlib_dfltcc_support); | |
| 114 | 116 | |
| 115 | 117 | unsigned long VMALLOC_START; |
| 116 | 118 | EXPORT_SYMBOL(VMALLOC_START); |
| @@ -759,14 +761,6 @@ static void __init free_mem_detect_info(void) · 642 unmodified lines | ||
| 759 | 761 | memblock_free(start, size); |
| 760 | 762 | } |
| 761 | 763 | |
| 762 | −static void __init memblock_physmem_add(phys_addr_t start, phys_addr_t size) | |
| 763 | −{ | |
| 764 | − memblock_dbg("memblock_physmem_add: [%#016llx-%#016llx]\n", | |
| 765 | − start, start + size - 1); | |
| 766 | − memblock_add_range(&memblock.memory, start, size, 0, 0); | |
| 767 | − memblock_add_range(&memblock.physmem, start, size, 0, 0); | |
| 768 | −} | |
| 769 | − | |
| 770 | 764 | static const char * __init get_mem_info_source(void) |
| 771 | 765 | { |
| 772 | 766 | switch (mem_detect.info_source) { |
| @@ -791,8 +785,10 @@ static void __init memblock_add_mem_detect_info(void) · 18 unmodified lines | ||
| 791 | 785 | get_mem_info_source(), mem_detect.info_source); |
| 792 | 786 | /* keep memblock lists close to the kernel */ |
| 793 | 787 | memblock_set_bottom_up(true); |
| 794 | − for_each_mem_detect_block(i, &start, &end) | |
| 788 | + for_each_mem_detect_block(i, &start, &end) { | |
| 789 | + memblock_add(start, end - start); | |
| 795 | 790 | memblock_physmem_add(start, end - start); |
| 791 | + } | |
| 796 | 792 | memblock_set_bottom_up(false); |
| 797 | 793 | memblock_dump_all(); |
| 798 | 794 | } |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/acpi.h> |
| 28 | 28 | #include <linux/workqueue.h> |
| 29 | 29 | #include <linux/uaccess.h> |
| 30 | +#include <linux/units.h> | |
| 30 | 31 | |
| 31 | 32 | #define PREFIX "ACPI: " |
| 32 | 33 | |
| @@ -172,7 +173,7 @@ struct acpi_thermal { · 139 unmodified lines | ||
| 172 | 173 | struct acpi_handle_list devices; |
| 173 | 174 | struct thermal_zone_device *thermal_zone; |
| 174 | 175 | int tz_enabled; |
| 175 | − int kelvin_offset; | |
| 176 | + int kelvin_offset; /* in millidegrees */ | |
| 176 | 177 | struct work_struct thermal_check_work; |
| 177 | 178 | }; |
| 178 | 179 | |
| @@ -297,7 +298,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) · 118 unmodified lines | ||
| 297 | 298 | if (crt == -1) { |
| 298 | 299 | tz->trips.critical.flags.valid = 0; |
| 299 | 300 | } else if (crt > 0) { |
| 300 | − unsigned long crt_k = CELSIUS_TO_DECI_KELVIN(crt); | |
| 301 | + unsigned long crt_k = celsius_to_deci_kelvin(crt); | |
| 302 | + | |
| 301 | 303 | /* |
| 302 | 304 | * Allow override critical threshold |
| 303 | 305 | */ |
| @@ -333,7 +335,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) · 29 unmodified lines | ||
| 333 | 335 | if (psv == -1) { |
| 334 | 336 | status = AE_SUPPORT; |
| 335 | 337 | } else if (psv > 0) { |
| 336 | − tmp = CELSIUS_TO_DECI_KELVIN(psv); | |
| 338 | + tmp = celsius_to_deci_kelvin(psv); | |
| 337 | 339 | status = AE_OK; |
| 338 | 340 | } else { |
| 339 | 341 | status = acpi_evaluate_integer(tz->device->handle, |
| @@ -413,7 +415,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) · 73 unmodified lines | ||
| 413 | 415 | break; |
| 414 | 416 | if (i == 1) |
| 415 | 417 | tz->trips.active[0].temperature = |
| 416 | − CELSIUS_TO_DECI_KELVIN(act); | |
| 418 | + celsius_to_deci_kelvin(act); | |
| 417 | 419 | else |
| 418 | 420 | /* |
| 419 | 421 | * Don't allow override higher than |
| @@ -421,9 +423,9 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) · 1 unmodified line | ||
| 421 | 423 | */ |
| 422 | 424 | tz->trips.active[i - 1].temperature = |
| 423 | 425 | (tz->trips.active[i - 2].temperature < |
| 424 | − CELSIUS_TO_DECI_KELVIN(act) ? | |
| 426 | + celsius_to_deci_kelvin(act) ? | |
| 425 | 427 | tz->trips.active[i - 2].temperature : |
| 426 | − CELSIUS_TO_DECI_KELVIN(act)); | |
| 428 | + celsius_to_deci_kelvin(act)); | |
| 427 | 429 | break; |
| 428 | 430 | } else { |
| 429 | 431 | tz->trips.active[i].temperature = tmp; |
| @@ -519,7 +521,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) · 89 unmodified lines | ||
| 519 | 521 | if (result) |
| 520 | 522 | return result; |
| 521 | 523 | |
| 522 | − *temp = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET(tz->temperature, | |
| 524 | + *temp = deci_kelvin_to_millicelsius_with_offset(tz->temperature, | |
| 523 | 525 | tz->kelvin_offset); |
| 524 | 526 | return 0; |
| 525 | 527 | } |
| @@ -624,7 +626,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, · 98 unmodified lines | ||
| 624 | 626 | |
| 625 | 627 | if (tz->trips.critical.flags.valid) { |
| 626 | 628 | if (!trip) { |
| 627 | − *temp = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET( | |
| 629 | + *temp = deci_kelvin_to_millicelsius_with_offset( | |
| 628 | 630 | tz->trips.critical.temperature, |
| 629 | 631 | tz->kelvin_offset); |
| 630 | 632 | return 0; |
| @@ -634,7 +636,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, · 3 unmodified lines | ||
| 634 | 636 | |
| 635 | 637 | if (tz->trips.hot.flags.valid) { |
| 636 | 638 | if (!trip) { |
| 637 | − *temp = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET( | |
| 639 | + *temp = deci_kelvin_to_millicelsius_with_offset( | |
| 638 | 640 | tz->trips.hot.temperature, |
| 639 | 641 | tz->kelvin_offset); |
| 640 | 642 | return 0; |
| @@ -644,7 +646,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, · 3 unmodified lines | ||
| 644 | 646 | |
| 645 | 647 | if (tz->trips.passive.flags.valid) { |
| 646 | 648 | if (!trip) { |
| 647 | − *temp = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET( | |
| 649 | + *temp = deci_kelvin_to_millicelsius_with_offset( | |
| 648 | 650 | tz->trips.passive.temperature, |
| 649 | 651 | tz->kelvin_offset); |
| 650 | 652 | return 0; |
| @@ -655,7 +657,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, · 4 unmodified lines | ||
| 655 | 657 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && |
| 656 | 658 | tz->trips.active[i].flags.valid; i++) { |
| 657 | 659 | if (!trip) { |
| 658 | − *temp = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET( | |
| 660 | + *temp = deci_kelvin_to_millicelsius_with_offset( | |
| 659 | 661 | tz->trips.active[i].temperature, |
| 660 | 662 | tz->kelvin_offset); |
| 661 | 663 | return 0; |
| @@ -672,7 +674,7 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal, · 10 unmodified lines | ||
| 672 | 674 | struct acpi_thermal *tz = thermal->devdata; |
| 673 | 675 | |
| 674 | 676 | if (tz->trips.critical.flags.valid) { |
| 675 | − *temperature = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET( | |
| 677 | + *temperature = deci_kelvin_to_millicelsius_with_offset( | |
| 676 | 678 | tz->trips.critical.temperature, |
| 677 | 679 | tz->kelvin_offset); |
| 678 | 680 | return 0; |
| @@ -692,7 +694,7 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, · 13 unmodified lines | ||
| 692 | 694 | |
| 693 | 695 | if (type == THERMAL_TRIP_ACTIVE) { |
| 694 | 696 | int trip_temp; |
| 695 | − int temp = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET( | |
| 697 | + int temp = deci_kelvin_to_millicelsius_with_offset( | |
| 696 | 698 | tz->temperature, tz->kelvin_offset); |
| 697 | 699 | if (thermal_get_trip_temp(thermal, trip, &trip_temp)) |
| 698 | 700 | return -EINVAL; |
| @@ -1043,9 +1045,9 @@ static void acpi_thermal_guess_offset(struct acpi_thermal *tz) · 344 unmodified lines | ||
| 1043 | 1045 | { |
| 1044 | 1046 | if (tz->trips.critical.flags.valid && |
| 1045 | 1047 | (tz->trips.critical.temperature % 5) == 1) |
| 1046 | − tz->kelvin_offset = 2731; | |
| 1048 | + tz->kelvin_offset = 273100; | |
| 1047 | 1049 | else |
| 1048 | − tz->kelvin_offset = 2732; | |
| 1050 | + tz->kelvin_offset = 273200; | |
| 1049 | 1051 | } |
| 1050 | 1052 | |
| 1051 | 1053 | static void acpi_thermal_check_fn(struct work_struct *work) |
| @@ -1087,7 +1089,7 @@ static int acpi_thermal_add(struct acpi_device *device) · 35 unmodified lines | ||
| 1087 | 1089 | INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); |
| 1088 | 1090 | |
| 1089 | 1091 | pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), |
| 1090 | − acpi_device_bid(device), DECI_KELVIN_TO_CELSIUS(tz->temperature)); | |
| 1092 | + acpi_device_bid(device), deci_kelvin_to_celsius(tz->temperature)); | |
| 1091 | 1093 | goto end; |
| 1092 | 1094 | |
| 1093 | 1095 | free_memory: |
| @@ -70,20 +70,6 @@ void unregister_memory_notifier(struct notifier_block *nb) · 69 unmodified lines | ||
| 70 | 70 | } |
| 71 | 71 | EXPORT_SYMBOL(unregister_memory_notifier); |
| 72 | 72 | |
| 73 | −static ATOMIC_NOTIFIER_HEAD(memory_isolate_chain); | |
| 74 | − | |
| 75 | −int register_memory_isolate_notifier(struct notifier_block *nb) | |
| 76 | −{ | |
| 77 | − return atomic_notifier_chain_register(&memory_isolate_chain, nb); | |
| 78 | −} | |
| 79 | −EXPORT_SYMBOL(register_memory_isolate_notifier); | |
| 80 | − | |
| 81 | −void unregister_memory_isolate_notifier(struct notifier_block *nb) | |
| 82 | −{ | |
| 83 | − atomic_notifier_chain_unregister(&memory_isolate_chain, nb); | |
| 84 | −} | |
| 85 | −EXPORT_SYMBOL(unregister_memory_isolate_notifier); | |
| 86 | − | |
| 87 | 73 | static void memory_block_release(struct device *dev) |
| 88 | 74 | { |
| 89 | 75 | struct memory_block *mem = to_memory_block(dev); |
| @@ -175,11 +161,6 @@ int memory_notify(unsigned long val, void *v) · 85 unmodified lines | ||
| 175 | 161 | return blocking_notifier_call_chain(&memory_chain, val, v); |
| 176 | 162 | } |
| 177 | 163 | |
| 178 | −int memory_isolate_notify(unsigned long val, void *v) | |
| 179 | −{ | |
| 180 | − return atomic_notifier_call_chain(&memory_isolate_chain, val, v); | |
| 181 | −} | |
| 182 | − | |
| 183 | 164 | /* |
| 184 | 165 | * The probe routines leave the pages uninitialized, just as the bootmem code |
| 185 | 166 | * does. Make sure we do not access them, but instead use only information from |
| @@ -225,7 +206,7 @@ static bool pages_correctly_probed(unsigned long start_pfn) · 39 unmodified lines | ||
| 225 | 206 | */ |
| 226 | 207 | static int |
| 227 | 208 | memory_block_action(unsigned long start_section_nr, unsigned long action, |
| 228 | − int online_type) | |
| 209 | + int online_type, int nid) | |
| 229 | 210 | { |
| 230 | 211 | unsigned long start_pfn; |
| 231 | 212 | unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; |
| @@ -238,7 +219,7 @@ memory_block_action(unsigned long start_section_nr, unsigned long action, · 6 unmodified lines | ||
| 238 | 219 | if (!pages_correctly_probed(start_pfn)) |
| 239 | 220 | return -EBUSY; |
| 240 | 221 | |
| 241 | − ret = online_pages(start_pfn, nr_pages, online_type); | |
| 222 | + ret = online_pages(start_pfn, nr_pages, online_type, nid); | |
| 242 | 223 | break; |
| 243 | 224 | case MEM_OFFLINE: |
| 244 | 225 | ret = offline_pages(start_pfn, nr_pages); |
| @@ -264,7 +245,7 @@ static int memory_block_change_state(struct memory_block *mem, · 19 unmodified lines | ||
| 264 | 245 | mem->state = MEM_GOING_OFFLINE; |
| 265 | 246 | |
| 266 | 247 | ret = memory_block_action(mem->start_section_nr, to_state, |
| 267 | − mem->online_type); | |
| 248 | + mem->online_type, mem->nid); | |
| 268 | 249 | |
| 269 | 250 | mem->state = ret ? from_state_req : to_state; |
| 270 | 251 | |
| @@ -207,14 +207,17 @@ static inline void zram_fill_page(void *ptr, unsigned long len, · 206 unmodified lines | ||
| 207 | 207 | |
| 208 | 208 | static bool page_same_filled(void *ptr, unsigned long *element) |
| 209 | 209 | { |
| 210 | − unsigned int pos; | |
| 211 | 210 | unsigned long *page; |
| 212 | 211 | unsigned long val; |
| 212 | + unsigned int pos, last_pos = PAGE_SIZE / sizeof(*page) - 1; | |
| 213 | 213 | |
| 214 | 214 | page = (unsigned long *)ptr; |
| 215 | 215 | val = page[0]; |
| 216 | 216 | |
| 217 | − for (pos = 1; pos < PAGE_SIZE / sizeof(*page); pos++) { | |
| 217 | + if (val != page[last_pos]) | |
| 218 | + return false; | |
| 219 | + | |
| 220 | + for (pos = 1; pos < last_pos; pos++) { | |
| 218 | 221 | if (val != page[pos]) |
| 219 | 222 | return false; |
| 220 | 223 | } |
| @@ -626,7 +629,7 @@ static ssize_t writeback_store(struct device *dev, · 405 unmodified lines | ||
| 626 | 629 | struct bio bio; |
| 627 | 630 | struct bio_vec bio_vec; |
| 628 | 631 | struct page *page; |
| 629 | − ssize_t ret; | |
| 632 | + ssize_t ret = len; | |
| 630 | 633 | int mode; |
| 631 | 634 | unsigned long blk_idx = 0; |
| 632 | 635 | |
| @@ -762,7 +765,6 @@ next: · 129 unmodified lines | ||
| 762 | 765 | |
| 763 | 766 | if (blk_idx) |
| 764 | 767 | free_block_bdev(zram, blk_idx); |
| 765 | − ret = len; | |
| 766 | 768 | __free_page(page); |
| 767 | 769 | release_init_lock: |
| 768 | 770 | up_read(&zram->init_lock); |
| @@ -188,8 +188,8 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) · 187 unmodified lines | ||
| 188 | 188 | kfree(vsg->desc_pages); |
| 189 | 189 | /* fall through */ |
| 190 | 190 | case dr_via_pages_locked: |
| 191 | − put_user_pages_dirty_lock(vsg->pages, vsg->num_pages, | |
| 192 | − (vsg->direction == DMA_FROM_DEVICE)); | |
| 191 | + unpin_user_pages_dirty_lock(vsg->pages, vsg->num_pages, | |
| 192 | + (vsg->direction == DMA_FROM_DEVICE)); | |
| 193 | 193 | /* fall through */ |
| 194 | 194 | case dr_via_pages_alloc: |
| 195 | 195 | vfree(vsg->pages); |
| @@ -239,7 +239,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) · 43 unmodified lines | ||
| 239 | 239 | vsg->pages = vzalloc(array_size(sizeof(struct page *), vsg->num_pages)); |
| 240 | 240 | if (NULL == vsg->pages) |
| 241 | 241 | return -ENOMEM; |
| 242 | − ret = get_user_pages_fast((unsigned long)xfer->mem_addr, | |
| 242 | + ret = pin_user_pages_fast((unsigned long)xfer->mem_addr, | |
| 243 | 243 | vsg->num_pages, |
| 244 | 244 | vsg->direction == DMA_FROM_DEVICE ? FOLL_WRITE : 0, |
| 245 | 245 | vsg->pages); |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/log2.h> |
| 7 | 7 | #include <linux/err.h> |
| 8 | 8 | #include <linux/module.h> |
| 9 | +#include <linux/units.h> | |
| 9 | 10 | |
| 10 | 11 | #include "qcom-vadc-common.h" |
| 11 | 12 | |
| @@ -236,8 +237,7 @@ static int qcom_vadc_scale_die_temp(const struct vadc_linear_graph *calib_graph, · 224 unmodified lines | ||
| 236 | 237 | voltage = 0; |
| 237 | 238 | } |
| 238 | 239 | |
| 239 | − voltage -= KELVINMIL_CELSIUSMIL; | |
| 240 | − *result_mdec = voltage; | |
| 240 | + *result_mdec = milli_kelvin_to_millicelsius(voltage); | |
| 241 | 241 | |
| 242 | 242 | return 0; |
| 243 | 243 | } |
| @@ -325,7 +325,7 @@ static int qcom_vadc_scale_hw_calib_die_temp( · 81 unmodified lines | ||
| 325 | 325 | { |
| 326 | 326 | *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code, |
| 327 | 327 | prescale, data, 2); |
| 328 | − *result_mdec -= KELVINMIL_CELSIUSMIL; | |
| 328 | + *result_mdec = milli_kelvin_to_millicelsius(*result_mdec); | |
| 329 | 329 | |
| 330 | 330 | return 0; |
| 331 | 331 | } |
| @@ -38,7 +38,6 @@ · 37 unmodified lines | ||
| 38 | 38 | #define VADC_AVG_SAMPLES_MAX 512 |
| 39 | 39 | #define ADC5_AVG_SAMPLES_MAX 16 |
| 40 | 40 | |
| 41 | −#define KELVINMIL_CELSIUSMIL 273150 | |
| 42 | 41 | #define PMIC5_CHG_TEMP_SCALE_FACTOR 377500 |
| 43 | 42 | #define PMIC5_SMB_TEMP_CONSTANT 419400 |
| 44 | 43 | #define PMIC5_SMB_TEMP_SCALE_FACTOR 356 |
| @@ -54,7 +54,7 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->sg_nents, 0) { |
| 56 | 56 | page = sg_page_iter_page(&sg_iter); |
| 57 | − put_user_pages_dirty_lock(&page, 1, umem->writable && dirty); | |
| 57 | + unpin_user_pages_dirty_lock(&page, 1, umem->writable && dirty); | |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | sg_free_table(&umem->sg_head); |
| @@ -257,16 +257,13 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr, · 196 unmodified lines | ||
| 257 | 257 | sg = umem->sg_head.sgl; |
| 258 | 258 | |
| 259 | 259 | while (npages) { |
| 260 | − down_read(&mm->mmap_sem); | |
| 261 | − ret = get_user_pages(cur_base, | |
| 262 | − min_t(unsigned long, npages, | |
| 263 | − PAGE_SIZE / sizeof (struct page *)), | |
| 264 | − gup_flags | FOLL_LONGTERM, | |
| 265 | − page_list, NULL); | |
| 266 | − if (ret < 0) { | |
| 267 | − up_read(&mm->mmap_sem); | |
| 260 | + ret = pin_user_pages_fast(cur_base, | |
| 261 | + min_t(unsigned long, npages, | |
| 262 | + PAGE_SIZE / | |
| 263 | + sizeof(struct page *)), | |
| 264 | + gup_flags | FOLL_LONGTERM, page_list); | |
| 265 | + if (ret < 0) | |
| 268 | 266 | goto umem_release; |
| 269 | − } | |
| 270 | 267 | |
| 271 | 268 | cur_base += ret * PAGE_SIZE; |
| 272 | 269 | npages -= ret; |
| @@ -274,8 +271,6 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr, · 1 unmodified line | ||
| 274 | 271 | sg = ib_umem_add_sg_table(sg, page_list, ret, |
| 275 | 272 | dma_get_max_seg_size(device->dma_device), |
| 276 | 273 | &umem->sg_nents); |
| 277 | − | |
| 278 | − up_read(&mm->mmap_sem); | |
| 279 | 274 | } |
| 280 | 275 | |
| 281 | 276 | sg_mark_end(sg); |
| @@ -293,9 +293,8 @@ EXPORT_SYMBOL(ib_umem_odp_release); · 292 unmodified lines | ||
| 293 | 293 | * The function returns -EFAULT if the DMA mapping operation fails. It returns |
| 294 | 294 | * -EAGAIN if a concurrent invalidation prevents us from updating the page. |
| 295 | 295 | * |
| 296 | − * The page is released via put_user_page even if the operation failed. For | |
| 297 | − * on-demand pinning, the page is released whenever it isn't stored in the | |
| 298 | − * umem. | |
| 296 | + * The page is released via put_page even if the operation failed. For on-demand | |
| 297 | + * pinning, the page is released whenever it isn't stored in the umem. | |
| 299 | 298 | */ |
| 300 | 299 | static int ib_umem_odp_map_dma_single_page( |
| 301 | 300 | struct ib_umem_odp *umem_odp, |
| @@ -348,7 +347,7 @@ static int ib_umem_odp_map_dma_single_page( · 46 unmodified lines | ||
| 348 | 347 | } |
| 349 | 348 | |
| 350 | 349 | out: |
| 351 | − put_user_page(page); | |
| 350 | + put_page(page); | |
| 352 | 351 | return ret; |
| 353 | 352 | } |
| 354 | 353 | |
| @@ -458,7 +457,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt, · 103 unmodified lines | ||
| 458 | 457 | ret = -EFAULT; |
| 459 | 458 | break; |
| 460 | 459 | } |
| 461 | − put_user_page(local_page_list[j]); | |
| 460 | + put_page(local_page_list[j]); | |
| 462 | 461 | continue; |
| 463 | 462 | } |
| 464 | 463 | |
| @@ -485,8 +484,8 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt, · 20 unmodified lines | ||
| 485 | 484 | * ib_umem_odp_map_dma_single_page(). |
| 486 | 485 | */ |
| 487 | 486 | if (npages - (j + 1) > 0) |
| 488 | − put_user_pages(&local_page_list[j+1], | |
| 489 | − npages - (j + 1)); | |
| 487 | + release_pages(&local_page_list[j+1], | |
| 488 | + npages - (j + 1)); | |
| 490 | 489 | break; |
| 491 | 490 | } |
| 492 | 491 | } |
| @@ -106,7 +106,7 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, size_t np · 105 unmodified lines | ||
| 106 | 106 | int ret; |
| 107 | 107 | unsigned int gup_flags = FOLL_LONGTERM | (writable ? FOLL_WRITE : 0); |
| 108 | 108 | |
| 109 | − ret = get_user_pages_fast(vaddr, npages, gup_flags, pages); | |
| 109 | + ret = pin_user_pages_fast(vaddr, npages, gup_flags, pages); | |
| 110 | 110 | if (ret < 0) |
| 111 | 111 | return ret; |
| 112 | 112 | |
| @@ -118,7 +118,7 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, size_t np · 5 unmodified lines | ||
| 118 | 118 | void hfi1_release_user_pages(struct mm_struct *mm, struct page **p, |
| 119 | 119 | size_t npages, bool dirty) |
| 120 | 120 | { |
| 121 | − put_user_pages_dirty_lock(p, npages, dirty); | |
| 121 | + unpin_user_pages_dirty_lock(p, npages, dirty); | |
| 122 | 122 | |
| 123 | 123 | if (mm) { /* during close after signal, mm can be NULL */ |
| 124 | 124 | atomic64_sub(npages, &mm->pinned_vm); |
| @@ -472,7 +472,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, · 471 unmodified lines | ||
| 472 | 472 | goto out; |
| 473 | 473 | } |
| 474 | 474 | |
| 475 | − ret = get_user_pages_fast(uaddr & PAGE_MASK, 1, | |
| 475 | + ret = pin_user_pages_fast(uaddr & PAGE_MASK, 1, | |
| 476 | 476 | FOLL_WRITE | FOLL_LONGTERM, pages); |
| 477 | 477 | if (ret < 0) |
| 478 | 478 | goto out; |
| @@ -482,7 +482,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, · 3 unmodified lines | ||
| 482 | 482 | |
| 483 | 483 | ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); |
| 484 | 484 | if (ret < 0) { |
| 485 | − put_user_page(pages[0]); | |
| 485 | + unpin_user_page(pages[0]); | |
| 486 | 486 | goto out; |
| 487 | 487 | } |
| 488 | 488 | |
| @@ -490,7 +490,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, · 1 unmodified line | ||
| 490 | 490 | mthca_uarc_virt(dev, uar, i)); |
| 491 | 491 | if (ret) { |
| 492 | 492 | pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); |
| 493 | − put_user_page(sg_page(&db_tab->page[i].mem)); | |
| 493 | + unpin_user_page(sg_page(&db_tab->page[i].mem)); | |
| 494 | 494 | goto out; |
| 495 | 495 | } |
| 496 | 496 | |
| @@ -556,7 +556,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, · 59 unmodified lines | ||
| 556 | 556 | if (db_tab->page[i].uvirt) { |
| 557 | 557 | mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1); |
| 558 | 558 | pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); |
| 559 | − put_user_page(sg_page(&db_tab->page[i].mem)); | |
| 559 | + unpin_user_page(sg_page(&db_tab->page[i].mem)); | |
| 560 | 560 | } |
| 561 | 561 | } |
| 562 | 562 | |
| @@ -40,7 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | static void __qib_release_user_pages(struct page **p, size_t num_pages, |
| 41 | 41 | int dirty) |
| 42 | 42 | { |
| 43 | − put_user_pages_dirty_lock(p, num_pages, dirty); | |
| 43 | + unpin_user_pages_dirty_lock(p, num_pages, dirty); | |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | /** |
| @@ -108,7 +108,7 @@ int qib_get_user_pages(unsigned long start_page, size_t num_pages, · 61 unmodified lines | ||
| 108 | 108 | |
| 109 | 109 | down_read(¤t->mm->mmap_sem); |
| 110 | 110 | for (got = 0; got < num_pages; got += ret) { |
| 111 | − ret = get_user_pages(start_page + got * PAGE_SIZE, | |
| 111 | + ret = pin_user_pages(start_page + got * PAGE_SIZE, | |
| 112 | 112 | num_pages - got, |
| 113 | 113 | FOLL_LONGTERM | FOLL_WRITE | FOLL_FORCE, |
| 114 | 114 | p + got, NULL); |
| @@ -317,7 +317,7 @@ static int qib_user_sdma_page_to_frags(const struct qib_devdata *dd, · 316 unmodified lines | ||
| 317 | 317 | * the caller can ignore this page. |
| 318 | 318 | */ |
| 319 | 319 | if (put) { |
| 320 | − put_user_page(page); | |
| 320 | + unpin_user_page(page); | |
| 321 | 321 | } else { |
| 322 | 322 | /* coalesce case */ |
| 323 | 323 | kunmap(page); |
| @@ -631,7 +631,7 @@ static void qib_user_sdma_free_pkt_frag(struct device *dev, · 307 unmodified lines | ||
| 631 | 631 | kunmap(pkt->addr[i].page); |
| 632 | 632 | |
| 633 | 633 | if (pkt->addr[i].put_page) |
| 634 | − put_user_page(pkt->addr[i].page); | |
| 634 | + unpin_user_page(pkt->addr[i].page); | |
| 635 | 635 | else |
| 636 | 636 | __free_page(pkt->addr[i].page); |
| 637 | 637 | } else if (pkt->addr[i].kvaddr) { |
| @@ -670,7 +670,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd, · 32 unmodified lines | ||
| 670 | 670 | else |
| 671 | 671 | j = npages; |
| 672 | 672 | |
| 673 | − ret = get_user_pages_fast(addr, j, FOLL_LONGTERM, pages); | |
| 673 | + ret = pin_user_pages_fast(addr, j, FOLL_LONGTERM, pages); | |
| 674 | 674 | if (ret != j) { |
| 675 | 675 | i = 0; |
| 676 | 676 | j = ret; |
| @@ -706,7 +706,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd, · 29 unmodified lines | ||
| 706 | 706 | /* if error, return all pages not managed by pkt */ |
| 707 | 707 | free_pages: |
| 708 | 708 | while (i < j) |
| 709 | − put_user_page(pages[i++]); | |
| 709 | + unpin_user_page(pages[i++]); | |
| 710 | 710 | |
| 711 | 711 | done: |
| 712 | 712 | return ret; |
| @@ -75,7 +75,7 @@ static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty) · 74 unmodified lines | ||
| 75 | 75 | for_each_sg(chunk->page_list, sg, chunk->nents, i) { |
| 76 | 76 | page = sg_page(sg); |
| 77 | 77 | pa = sg_phys(sg); |
| 78 | − put_user_pages_dirty_lock(&page, 1, dirty); | |
| 78 | + unpin_user_pages_dirty_lock(&page, 1, dirty); | |
| 79 | 79 | usnic_dbg("pa: %pa\n", &pa); |
| 80 | 80 | } |
| 81 | 81 | kfree(chunk); |
| @@ -141,7 +141,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, · 59 unmodified lines | ||
| 141 | 141 | ret = 0; |
| 142 | 142 | |
| 143 | 143 | while (npages) { |
| 144 | − ret = get_user_pages(cur_base, | |
| 144 | + ret = pin_user_pages(cur_base, | |
| 145 | 145 | min_t(unsigned long, npages, |
| 146 | 146 | PAGE_SIZE / sizeof(struct page *)), |
| 147 | 147 | gup_flags | FOLL_LONGTERM, |
| @@ -63,7 +63,7 @@ struct siw_mem *siw_mem_id2obj(struct siw_device *sdev, int stag_index) · 62 unmodified lines | ||
| 63 | 63 | static void siw_free_plist(struct siw_page_chunk *chunk, int num_pages, |
| 64 | 64 | bool dirty) |
| 65 | 65 | { |
| 66 | − put_user_pages_dirty_lock(chunk->plist, num_pages, dirty); | |
| 66 | + unpin_user_pages_dirty_lock(chunk->plist, num_pages, dirty); | |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | void siw_umem_release(struct siw_umem *umem, bool dirty) |
| @@ -426,7 +426,7 @@ struct siw_umem *siw_umem_get(u64 start, u64 len, bool writable) · 356 unmodified lines | ||
| 426 | 426 | while (nents) { |
| 427 | 427 | struct page **plist = &umem->page_chunk[i].plist[got]; |
| 428 | 428 | |
| 429 | − rv = get_user_pages(first_page_va, nents, | |
| 429 | + rv = pin_user_pages(first_page_va, nents, | |
| 430 | 430 | foll_flags | FOLL_LONGTERM, |
| 431 | 431 | plist, NULL); |
| 432 | 432 | if (rv < 0) |
| @@ -183,12 +183,12 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, · 182 unmodified lines | ||
| 183 | 183 | dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n", |
| 184 | 184 | data, size, dma->nr_pages); |
| 185 | 185 | |
| 186 | − err = get_user_pages(data & PAGE_MASK, dma->nr_pages, | |
| 186 | + err = pin_user_pages(data & PAGE_MASK, dma->nr_pages, | |
| 187 | 187 | flags | FOLL_LONGTERM, dma->pages, NULL); |
| 188 | 188 | |
| 189 | 189 | if (err != dma->nr_pages) { |
| 190 | 190 | dma->nr_pages = (err >= 0) ? err : 0; |
| 191 | − dprintk(1, "get_user_pages: err=%d [%d]\n", err, | |
| 191 | + dprintk(1, "pin_user_pages: err=%d [%d]\n", err, | |
| 192 | 192 | dma->nr_pages); |
| 193 | 193 | return err < 0 ? err : -EINVAL; |
| 194 | 194 | } |
| @@ -349,8 +349,8 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma) · 154 unmodified lines | ||
| 349 | 349 | BUG_ON(dma->sglen); |
| 350 | 350 | |
| 351 | 351 | if (dma->pages) { |
| 352 | − for (i = 0; i < dma->nr_pages; i++) | |
| 353 | − put_page(dma->pages[i]); | |
| 352 | + unpin_user_pages_dirty_lock(dma->pages, dma->nr_pages, | |
| 353 | + dma->direction == DMA_FROM_DEVICE); | |
| 354 | 354 | kfree(dma->pages); |
| 355 | 355 | dma->pages = NULL; |
| 356 | 356 | } |
| @@ -296,7 +296,6 @@ static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode, · 295 unmodified lines | ||
| 296 | 296 | * possible, the driver should only write the valid vnics into the internal |
| 297 | 297 | * ram according to the appropriate port mode. |
| 298 | 298 | */ |
| 299 | −#define BITS_TO_BYTES(x) ((x)/8) | |
| 300 | 299 | |
| 301 | 300 | /* CMNG constants, as derived from system spec calculations */ |
| 302 | 301 | |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/firmware.h> |
| 28 | 28 | #include <linux/etherdevice.h> |
| 29 | 29 | #include <linux/if_arp.h> |
| 30 | +#include <linux/units.h> | |
| 30 | 31 | |
| 31 | 32 | #include <net/mac80211.h> |
| 32 | 33 | |
| @@ -6468,7 +6469,7 @@ il4965_set_hw_params(struct il_priv *il) · 6435 unmodified lines | ||
| 6468 | 6469 | il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant; |
| 6469 | 6470 | |
| 6470 | 6471 | il->hw_params.ct_kill_threshold = |
| 6471 | − CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); | |
| 6472 | + celsius_to_kelvin(CT_KILL_THRESHOLD_LEGACY); | |
| 6472 | 6473 | |
| 6473 | 6474 | il->hw_params.sens = &il4965_sensitivity; |
| 6474 | 6475 | il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS; |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/sched.h> |
| 18 | 18 | #include <linux/skbuff.h> |
| 19 | 19 | #include <linux/netdevice.h> |
| 20 | +#include <linux/units.h> | |
| 20 | 21 | #include <net/mac80211.h> |
| 21 | 22 | #include <linux/etherdevice.h> |
| 22 | 23 | #include <asm/unaligned.h> |
| @@ -1104,7 +1105,7 @@ il4965_fill_txpower_tbl(struct il_priv *il, u8 band, u16 channel, u8 is_ht40, · 1081 unmodified lines | ||
| 1104 | 1105 | /* get current temperature (Celsius) */ |
| 1105 | 1106 | current_temp = max(il->temperature, IL_TX_POWER_TEMPERATURE_MIN); |
| 1106 | 1107 | current_temp = min(il->temperature, IL_TX_POWER_TEMPERATURE_MAX); |
| 1107 | − current_temp = KELVIN_TO_CELSIUS(current_temp); | |
| 1108 | + current_temp = kelvin_to_celsius(current_temp); | |
| 1108 | 1109 | |
| 1109 | 1110 | /* select thermal txpower adjustment params, based on channel group |
| 1110 | 1111 | * (same frequency group used for mimo txatten adjustment) */ |
| @@ -1610,8 +1611,8 @@ il4965_hw_get_temperature(struct il_priv *il) · 499 unmodified lines | ||
| 1610 | 1611 | temperature = |
| 1611 | 1612 | (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET; |
| 1612 | 1613 | |
| 1613 | − D_TEMP("Calibrated temperature: %dK, %dC\n", temperature, | |
| 1614 | − KELVIN_TO_CELSIUS(temperature)); | |
| 1614 | + D_TEMP("Calibrated temperature: %dK, %ldC\n", temperature, | |
| 1615 | + kelvin_to_celsius(temperature)); | |
| 1615 | 1616 | |
| 1616 | 1617 | return temperature; |
| 1617 | 1618 | } |
| @@ -1670,12 +1671,12 @@ il4965_temperature_calib(struct il_priv *il) · 52 unmodified lines | ||
| 1670 | 1671 | |
| 1671 | 1672 | if (il->temperature != temp) { |
| 1672 | 1673 | if (il->temperature) |
| 1673 | − D_TEMP("Temperature changed " "from %dC to %dC\n", | |
| 1674 | − KELVIN_TO_CELSIUS(il->temperature), | |
| 1675 | − KELVIN_TO_CELSIUS(temp)); | |
| 1674 | + D_TEMP("Temperature changed " "from %ldC to %ldC\n", | |
| 1675 | + kelvin_to_celsius(il->temperature), | |
| 1676 | + kelvin_to_celsius(temp)); | |
| 1676 | 1677 | else |
| 1677 | − D_TEMP("Temperature " "initialized to %dC\n", | |
| 1678 | − KELVIN_TO_CELSIUS(temp)); | |
| 1678 | + D_TEMP("Temperature " "initialized to %ldC\n", | |
| 1679 | + kelvin_to_celsius(temp)); | |
| 1679 | 1680 | } |
| 1680 | 1681 | |
| 1681 | 1682 | il->temperature = temp; |
| @@ -779,9 +779,6 @@ struct il_sensitivity_ranges { · 778 unmodified lines | ||
| 779 | 779 | u16 nrg_th_cca; |
| 780 | 780 | }; |
| 781 | 781 | |
| 782 | −#define KELVIN_TO_CELSIUS(x) ((x)-273) | |
| 783 | −#define CELSIUS_TO_KELVIN(x) ((x)+273) | |
| 784 | − | |
| 785 | 782 | /** |
| 786 | 783 | * struct il_hw_params |
| 787 | 784 | * @bcast_id: f/w broadcast station ID |
| @@ -237,11 +237,6 @@ struct iwl_sensitivity_ranges { · 236 unmodified lines | ||
| 237 | 237 | u16 nrg_th_cca; |
| 238 | 238 | }; |
| 239 | 239 | |
| 240 | − | |
| 241 | −#define KELVIN_TO_CELSIUS(x) ((x)-273) | |
| 242 | −#define CELSIUS_TO_KELVIN(x) ((x)+273) | |
| 243 | − | |
| 244 | − | |
| 245 | 240 | /****************************************************************************** |
| 246 | 241 | * |
| 247 | 242 | * Functions implemented in core module which are forward declared here |
| @@ -10,6 +10,8 @@ · 9 unmodified lines | ||
| 10 | 10 | * |
| 11 | 11 | *****************************************************************************/ |
| 12 | 12 | |
| 13 | +#include <linux/units.h> | |
| 14 | + | |
| 13 | 15 | /* |
| 14 | 16 | * DVM device-specific data & functions |
| 15 | 17 | */ |
| @@ -345,7 +347,7 @@ static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) · 329 unmodified lines | ||
| 345 | 347 | static void iwl5150_set_ct_threshold(struct iwl_priv *priv) |
| 346 | 348 | { |
| 347 | 349 | const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF; |
| 348 | − s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) - | |
| 350 | + s32 threshold = (s32)celsius_to_kelvin(CT_KILL_THRESHOLD_LEGACY) - | |
| 349 | 351 | iwl_temp_calib_to_offset(priv); |
| 350 | 352 | |
| 351 | 353 | priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef; |
| @@ -381,7 +383,7 @@ static void iwl5150_temperature(struct iwl_priv *priv) · 29 unmodified lines | ||
| 381 | 383 | vt = le32_to_cpu(priv->statistics.common.temperature); |
| 382 | 384 | vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; |
| 383 | 385 | /* now vt hold the temperature in Kelvin */ |
| 384 | − priv->temperature = KELVIN_TO_CELSIUS(vt); | |
| 386 | + priv->temperature = kelvin_to_celsius(vt); | |
| 385 | 387 | iwl_tt_handler(priv); |
| 386 | 388 | } |
| 387 | 389 | |
| @@ -337,13 +337,7 @@ static void pmem_release_disk(void *__pmem) · 336 unmodified lines | ||
| 337 | 337 | put_disk(pmem->disk); |
| 338 | 338 | } |
| 339 | 339 | |
| 340 | −static void pmem_pagemap_page_free(struct page *page) | |
| 341 | −{ | |
| 342 | − wake_up_var(&page->_refcount); | |
| 343 | −} | |
| 344 | − | |
| 345 | 340 | static const struct dev_pagemap_ops fsdax_pagemap_ops = { |
| 346 | − .page_free = pmem_pagemap_page_free, | |
| 347 | 341 | .kill = pmem_pagemap_kill, |
| 348 | 342 | .cleanup = pmem_pagemap_cleanup, |
| 349 | 343 | }; |
| @@ -5,14 +5,11 @@ · 4 unmodified lines | ||
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #include <linux/hwmon.h> |
| 8 | +#include <linux/units.h> | |
| 8 | 9 | #include <asm/unaligned.h> |
| 9 | 10 | |
| 10 | 11 | #include "nvme.h" |
| 11 | 12 | |
| 12 | −/* These macros should be moved to linux/temperature.h */ | |
| 13 | −#define MILLICELSIUS_TO_KELVIN(t) DIV_ROUND_CLOSEST((t) + 273150, 1000) | |
| 14 | −#define KELVIN_TO_MILLICELSIUS(t) ((t) * 1000L - 273150) | |
| 15 | − | |
| 16 | 13 | struct nvme_hwmon_data { |
| 17 | 14 | struct nvme_ctrl *ctrl; |
| 18 | 15 | struct nvme_smart_log log; |
| @@ -35,7 +32,7 @@ static int nvme_get_temp_thresh(struct nvme_ctrl *ctrl, int sensor, bool under, · 16 unmodified lines | ||
| 35 | 32 | return -EIO; |
| 36 | 33 | if (ret < 0) |
| 37 | 34 | return ret; |
| 38 | − *temp = KELVIN_TO_MILLICELSIUS(status & NVME_TEMP_THRESH_MASK); | |
| 35 | + *temp = kelvin_to_millicelsius(status & NVME_TEMP_THRESH_MASK); | |
| 39 | 36 | |
| 40 | 37 | return 0; |
| 41 | 38 | } |
| @@ -46,7 +43,7 @@ static int nvme_set_temp_thresh(struct nvme_ctrl *ctrl, int sensor, bool under, · 4 unmodified lines | ||
| 46 | 43 | unsigned int threshold = sensor << NVME_TEMP_THRESH_SELECT_SHIFT; |
| 47 | 44 | int ret; |
| 48 | 45 | |
| 49 | − temp = MILLICELSIUS_TO_KELVIN(temp); | |
| 46 | + temp = millicelsius_to_kelvin(temp); | |
| 50 | 47 | threshold |= clamp_val(temp, 0, NVME_TEMP_THRESH_MASK); |
| 51 | 48 | |
| 52 | 49 | if (under) |
| @@ -88,7 +85,7 @@ static int nvme_hwmon_read(struct device *dev, enum hwmon_sensor_types type, · 35 unmodified lines | ||
| 88 | 85 | case hwmon_temp_min: |
| 89 | 86 | return nvme_get_temp_thresh(data->ctrl, channel, true, val); |
| 90 | 87 | case hwmon_temp_crit: |
| 91 | − *val = KELVIN_TO_MILLICELSIUS(data->ctrl->cctemp); | |
| 88 | + *val = kelvin_to_millicelsius(data->ctrl->cctemp); | |
| 92 | 89 | return 0; |
| 93 | 90 | default: |
| 94 | 91 | break; |
| @@ -105,7 +102,7 @@ static int nvme_hwmon_read(struct device *dev, enum hwmon_sensor_types type, · 10 unmodified lines | ||
| 105 | 102 | temp = get_unaligned_le16(log->temperature); |
| 106 | 103 | else |
| 107 | 104 | temp = le16_to_cpu(log->temp_sensor[channel - 1]); |
| 108 | − *val = KELVIN_TO_MILLICELSIUS(temp); | |
| 105 | + *val = kelvin_to_millicelsius(temp); | |
| 109 | 106 | break; |
| 110 | 107 | case hwmon_temp_alarm: |
| 111 | 108 | *val = !!(log->critical_warning & NVME_SMART_CRIT_TEMPERATURE); |
| @@ -257,12 +257,12 @@ static int goldfish_pipe_error_convert(int status) · 256 unmodified lines | ||
| 257 | 257 | } |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | −static int pin_user_pages(unsigned long first_page, | |
| 261 | − unsigned long last_page, | |
| 262 | − unsigned int last_page_size, | |
| 263 | − int is_write, | |
| 264 | − struct page *pages[MAX_BUFFERS_PER_COMMAND], | |
| 265 | − unsigned int *iter_last_page_size) | |
| 260 | +static int goldfish_pin_pages(unsigned long first_page, | |
| 261 | + unsigned long last_page, | |
| 262 | + unsigned int last_page_size, | |
| 263 | + int is_write, | |
| 264 | + struct page *pages[MAX_BUFFERS_PER_COMMAND], | |
| 265 | + unsigned int *iter_last_page_size) | |
| 266 | 266 | { |
| 267 | 267 | int ret; |
| 268 | 268 | int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1; |
| @@ -274,7 +274,7 @@ static int pin_user_pages(unsigned long first_page, · 5 unmodified lines | ||
| 274 | 274 | *iter_last_page_size = last_page_size; |
| 275 | 275 | } |
| 276 | 276 | |
| 277 | − ret = get_user_pages_fast(first_page, requested_pages, | |
| 277 | + ret = pin_user_pages_fast(first_page, requested_pages, | |
| 278 | 278 | !is_write ? FOLL_WRITE : 0, |
| 279 | 279 | pages); |
| 280 | 280 | if (ret <= 0) |
| @@ -285,18 +285,6 @@ static int pin_user_pages(unsigned long first_page, · 4 unmodified lines | ||
| 285 | 285 | return ret; |
| 286 | 286 | } |
| 287 | 287 | |
| 288 | −static void release_user_pages(struct page **pages, int pages_count, | |
| 289 | − int is_write, s32 consumed_size) | |
| 290 | −{ | |
| 291 | − int i; | |
| 292 | − | |
| 293 | − for (i = 0; i < pages_count; i++) { | |
| 294 | − if (!is_write && consumed_size > 0) | |
| 295 | − set_page_dirty(pages[i]); | |
| 296 | − put_page(pages[i]); | |
| 297 | − } | |
| 298 | −} | |
| 299 | − | |
| 300 | 288 | /* Populate the call parameters, merging adjacent pages together */ |
| 301 | 289 | static void populate_rw_params(struct page **pages, |
| 302 | 290 | int pages_count, |
| @@ -354,9 +342,9 @@ static int transfer_max_buffers(struct goldfish_pipe *pipe, · 51 unmodified lines | ||
| 354 | 342 | if (mutex_lock_interruptible(&pipe->lock)) |
| 355 | 343 | return -ERESTARTSYS; |
| 356 | 344 | |
| 357 | − pages_count = pin_user_pages(first_page, last_page, | |
| 358 | − last_page_size, is_write, | |
| 359 | − pipe->pages, &iter_last_page_size); | |
| 345 | + pages_count = goldfish_pin_pages(first_page, last_page, | |
| 346 | + last_page_size, is_write, | |
| 347 | + pipe->pages, &iter_last_page_size); | |
| 360 | 348 | if (pages_count < 0) { |
| 361 | 349 | mutex_unlock(&pipe->lock); |
| 362 | 350 | return pages_count; |
| @@ -372,7 +360,8 @@ static int transfer_max_buffers(struct goldfish_pipe *pipe, · 9 unmodified lines | ||
| 372 | 360 | |
| 373 | 361 | *consumed_size = pipe->command_buffer->rw_params.consumed_size; |
| 374 | 362 | |
| 375 | − release_user_pages(pipe->pages, pages_count, is_write, *consumed_size); | |
| 363 | + unpin_user_pages_dirty_lock(pipe->pages, pages_count, | |
| 364 | + !is_write && *consumed_size > 0); | |
| 376 | 365 | |
| 377 | 366 | mutex_unlock(&pipe->lock); |
| 378 | 367 | return 0; |
| @@ -33,9 +33,9 @@ · 32 unmodified lines | ||
| 33 | 33 | #include <linux/seq_file.h> |
| 34 | 34 | #include <linux/platform_data/x86/asus-wmi.h> |
| 35 | 35 | #include <linux/platform_device.h> |
| 36 | −#include <linux/thermal.h> | |
| 37 | 36 | #include <linux/acpi.h> |
| 38 | 37 | #include <linux/dmi.h> |
| 38 | +#include <linux/units.h> | |
| 39 | 39 | |
| 40 | 40 | #include <acpi/battery.h> |
| 41 | 41 | #include <acpi/video.h> |
| @@ -1514,9 +1514,8 @@ static ssize_t asus_hwmon_temp1(struct device *dev, · 1472 unmodified lines | ||
| 1514 | 1514 | if (err < 0) |
| 1515 | 1515 | return err; |
| 1516 | 1516 | |
| 1517 | − value = DECI_KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000; | |
| 1518 | − | |
| 1519 | − return sprintf(buf, "%d\n", value); | |
| 1517 | + return sprintf(buf, "%ld\n", | |
| 1518 | + deci_kelvin_to_millicelsius(value & 0xFFFF)); | |
| 1520 | 1519 | } |
| 1521 | 1520 | |
| 1522 | 1521 | /* Fan1 */ |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/slab.h> |
| 23 | 23 | #include <linux/thermal.h> |
| 24 | 24 | #include <linux/types.h> |
| 25 | +#include <linux/units.h> | |
| 25 | 26 | |
| 26 | 27 | MODULE_AUTHOR("Thomas Sujith"); |
| 27 | 28 | MODULE_AUTHOR("Zhang Rui"); |
| @@ -302,8 +303,10 @@ static ssize_t aux_show(struct device *dev, struct device_attribute *dev_attr, · 274 unmodified lines | ||
| 302 | 303 | int result; |
| 303 | 304 | |
| 304 | 305 | result = sensor_get_auxtrip(attr->handle, idx, &value); |
| 306 | + if (result) | |
| 307 | + return result; | |
| 305 | 308 | |
| 306 | − return result ? result : sprintf(buf, "%lu", DECI_KELVIN_TO_CELSIUS(value)); | |
| 309 | + return sprintf(buf, "%lu", deci_kelvin_to_celsius(value)); | |
| 307 | 310 | } |
| 308 | 311 | |
| 309 | 312 | static ssize_t aux0_show(struct device *dev, |
| @@ -332,8 +335,8 @@ static ssize_t aux_store(struct device *dev, struct device_attribute *dev_attr, · 22 unmodified lines | ||
| 332 | 335 | if (value < 0) |
| 333 | 336 | return -EINVAL; |
| 334 | 337 | |
| 335 | − result = sensor_set_auxtrip(attr->handle, idx, | |
| 336 | − CELSIUS_TO_DECI_KELVIN(value)); | |
| 338 | + result = sensor_set_auxtrip(attr->handle, idx, | |
| 339 | + celsius_to_deci_kelvin(value)); | |
| 337 | 340 | return result ? result : count; |
| 338 | 341 | } |
| 339 | 342 | |
| @@ -21,8 +21,6 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | #include "thermal_core.h" |
| 23 | 23 | |
| 24 | −#define TO_MCELSIUS(c) ((c) * 1000) | |
| 25 | − | |
| 26 | 24 | /* Thermal Manager Control and Status Register */ |
| 27 | 25 | #define PMU_TDC0_SW_RST_MASK (0x1 << 1) |
| 28 | 26 | #define PMU_TM_DISABLE_OFFS 0 |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/init.h> |
| 9 | 9 | #include <linux/acpi.h> |
| 10 | 10 | #include <linux/thermal.h> |
| 11 | +#include <linux/units.h> | |
| 11 | 12 | #include "int340x_thermal_zone.h" |
| 12 | 13 | |
| 13 | 14 | static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, |
| @@ -34,7 +35,7 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, · 20 unmodified lines | ||
| 34 | 35 | *temp = (unsigned long)conv_temp * 10; |
| 35 | 36 | } else |
| 36 | 37 | /* _TMP returns the temperature in tenths of degrees Kelvin */ |
| 37 | − *temp = DECI_KELVIN_TO_MILLICELSIUS(tmp); | |
| 38 | + *temp = deci_kelvin_to_millicelsius(tmp); | |
| 38 | 39 | |
| 39 | 40 | return 0; |
| 40 | 41 | } |
| @@ -116,7 +117,7 @@ static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, · 75 unmodified lines | ||
| 116 | 117 | |
| 117 | 118 | snprintf(name, sizeof(name), "PAT%d", trip); |
| 118 | 119 | status = acpi_execute_simple_method(d->adev->handle, name, |
| 119 | − MILLICELSIUS_TO_DECI_KELVIN(temp)); | |
| 120 | + millicelsius_to_deci_kelvin(temp)); | |
| 120 | 121 | if (ACPI_FAILURE(status)) |
| 121 | 122 | return -EIO; |
| 122 | 123 | |
| @@ -163,7 +164,7 @@ static int int340x_thermal_get_trip_config(acpi_handle handle, char *name, · 40 unmodified lines | ||
| 163 | 164 | if (ACPI_FAILURE(status)) |
| 164 | 165 | return -EIO; |
| 165 | 166 | |
| 166 | − *temp = DECI_KELVIN_TO_MILLICELSIUS(r); | |
| 167 | + *temp = deci_kelvin_to_millicelsius(r); | |
| 167 | 168 | |
| 168 | 169 | return 0; |
| 169 | 170 | } |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/pci.h> |
| 14 | 14 | #include <linux/acpi.h> |
| 15 | 15 | #include <linux/thermal.h> |
| 16 | +#include <linux/units.h> | |
| 16 | 17 | #include <linux/pm.h> |
| 17 | 18 | |
| 18 | 19 | /* Intel PCH thermal Device IDs */ |
| @@ -93,7 +94,7 @@ static void pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, · 74 unmodified lines | ||
| 93 | 94 | if (ACPI_SUCCESS(status)) { |
| 94 | 95 | unsigned long trip_temp; |
| 95 | 96 | |
| 96 | − trip_temp = DECI_KELVIN_TO_MILLICELSIUS(r); | |
| 97 | + trip_temp = deci_kelvin_to_millicelsius(r); | |
| 97 | 98 | if (trip_temp) { |
| 98 | 99 | ptd->psv_temp = trip_temp; |
| 99 | 100 | ptd->psv_trip_id = *nr_trips; |
| @@ -309,9 +309,8 @@ static int put_pfn(unsigned long pfn, int prot) · 308 unmodified lines | ||
| 309 | 309 | { |
| 310 | 310 | if (!is_invalid_reserved_pfn(pfn)) { |
| 311 | 311 | struct page *page = pfn_to_page(pfn); |
| 312 | − if (prot & IOMMU_WRITE) | |
| 313 | − SetPageDirty(page); | |
| 314 | − put_page(page); | |
| 312 | + | |
| 313 | + unpin_user_pages_dirty_lock(&page, 1, prot & IOMMU_WRITE); | |
| 315 | 314 | return 1; |
| 316 | 315 | } |
| 317 | 316 | return 0; |
| @@ -322,7 +321,6 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, · 4 unmodified lines | ||
| 322 | 321 | { |
| 323 | 322 | struct page *page[1]; |
| 324 | 323 | struct vm_area_struct *vma; |
| 325 | − struct vm_area_struct *vmas[1]; | |
| 326 | 324 | unsigned int flags = 0; |
| 327 | 325 | int ret; |
| 328 | 326 | |
| @@ -330,33 +328,14 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, · 1 unmodified line | ||
| 330 | 328 | flags |= FOLL_WRITE; |
| 331 | 329 | |
| 332 | 330 | down_read(&mm->mmap_sem); |
| 333 | − if (mm == current->mm) { | |
| 334 | − ret = get_user_pages(vaddr, 1, flags | FOLL_LONGTERM, page, | |
| 335 | − vmas); | |
| 336 | − } else { | |
| 337 | − ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags, page, | |
| 338 | − vmas, NULL); | |
| 339 | − /* | |
| 340 | − * The lifetime of a vaddr_get_pfn() page pin is | |
| 341 | − * userspace-controlled. In the fs-dax case this could | |
| 342 | − * lead to indefinite stalls in filesystem operations. | |
| 343 | − * Disallow attempts to pin fs-dax pages via this | |
| 344 | − * interface. | |
| 345 | − */ | |
| 346 | − if (ret > 0 && vma_is_fsdax(vmas[0])) { | |
| 347 | − ret = -EOPNOTSUPP; | |
| 348 | − put_page(page[0]); | |
| 349 | − } | |
| 350 | − } | |
| 351 | − up_read(&mm->mmap_sem); | |
| 352 | − | |
| 331 | + ret = pin_user_pages_remote(NULL, mm, vaddr, 1, flags | FOLL_LONGTERM, | |
| 332 | + page, NULL, NULL); | |
| 353 | 333 | if (ret == 1) { |
| 354 | 334 | *pfn = page_to_pfn(page[0]); |
| 355 | − return 0; | |
| 335 | + ret = 0; | |
| 336 | + goto done; | |
| 356 | 337 | } |
| 357 | 338 | |
| 358 | − down_read(&mm->mmap_sem); | |
| 359 | − | |
| 360 | 339 | vaddr = untagged_addr(vaddr); |
| 361 | 340 | |
| 362 | 341 | vma = find_vma_intersection(mm, vaddr, vaddr + 1); |
| @@ -366,7 +345,7 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, · 3 unmodified lines | ||
| 366 | 345 | if (is_invalid_reserved_pfn(*pfn)) |
| 367 | 346 | ret = 0; |
| 368 | 347 | } |
| 369 | − | |
| 348 | +done: | |
| 370 | 349 | up_read(&mm->mmap_sem); |
| 371 | 350 | return ret; |
| 372 | 351 | } |
| @@ -97,7 +97,7 @@ static struct linux_binfmt elf_format = { · 96 unmodified lines | ||
| 97 | 97 | .min_coredump = ELF_EXEC_PAGESIZE, |
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | −#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) | |
| 100 | +#define BAD_ADDR(x) (unlikely((unsigned long)(x) >= TASK_SIZE)) | |
| 101 | 101 | |
| 102 | 102 | static int set_brk(unsigned long start, unsigned long end, int prot) |
| 103 | 103 | { |
| @@ -161,9 +161,11 @@ static int padzero(unsigned long elf_bss) · 57 unmodified lines | ||
| 161 | 161 | #endif |
| 162 | 162 | |
| 163 | 163 | static int |
| 164 | −create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |
| 165 | − unsigned long load_addr, unsigned long interp_load_addr) | |
| 164 | +create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec, | |
| 165 | + unsigned long load_addr, unsigned long interp_load_addr, | |
| 166 | + unsigned long e_entry) | |
| 166 | 167 | { |
| 168 | + struct mm_struct *mm = current->mm; | |
| 167 | 169 | unsigned long p = bprm->p; |
| 168 | 170 | int argc = bprm->argc; |
| 169 | 171 | int envc = bprm->envc; |
| @@ -176,7 +178,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, · 6 unmodified lines | ||
| 176 | 178 | unsigned char k_rand_bytes[16]; |
| 177 | 179 | int items; |
| 178 | 180 | elf_addr_t *elf_info; |
| 179 | − int ei_index = 0; | |
| 181 | + int ei_index; | |
| 180 | 182 | const struct cred *cred = current_cred(); |
| 181 | 183 | struct vm_area_struct *vma; |
| 182 | 184 | |
| @@ -226,12 +228,12 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, · 43 unmodified lines | ||
| 226 | 228 | return -EFAULT; |
| 227 | 229 | |
| 228 | 230 | /* Create the ELF interpreter info */ |
| 229 | − elf_info = (elf_addr_t *)current->mm->saved_auxv; | |
| 231 | + elf_info = (elf_addr_t *)mm->saved_auxv; | |
| 230 | 232 | /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ |
| 231 | 233 | #define NEW_AUX_ENT(id, val) \ |
| 232 | 234 | do { \ |
| 233 | − elf_info[ei_index++] = id; \ | |
| 234 | − elf_info[ei_index++] = val; \ | |
| 235 | + *elf_info++ = id; \ | |
| 236 | + *elf_info++ = val; \ | |
| 235 | 237 | } while (0) |
| 236 | 238 | |
| 237 | 239 | #ifdef ARCH_DLINFO |
| @@ -251,7 +253,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, · 13 unmodified lines | ||
| 251 | 253 | NEW_AUX_ENT(AT_PHNUM, exec->e_phnum); |
| 252 | 254 | NEW_AUX_ENT(AT_BASE, interp_load_addr); |
| 253 | 255 | NEW_AUX_ENT(AT_FLAGS, 0); |
| 254 | − NEW_AUX_ENT(AT_ENTRY, exec->e_entry); | |
| 256 | + NEW_AUX_ENT(AT_ENTRY, e_entry); | |
| 255 | 257 | NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid)); |
| 256 | 258 | NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid)); |
| 257 | 259 | NEW_AUX_ENT(AT_GID, from_kgid_munged(cred->user_ns, cred->gid)); |
| @@ -275,12 +277,13 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, · 17 unmodified lines | ||
| 275 | 277 | } |
| 276 | 278 | #undef NEW_AUX_ENT |
| 277 | 279 | /* AT_NULL is zero; clear the rest too */ |
| 278 | − memset(&elf_info[ei_index], 0, | |
| 279 | − sizeof current->mm->saved_auxv - ei_index * sizeof elf_info[0]); | |
| 280 | + memset(elf_info, 0, (char *)mm->saved_auxv + | |
| 281 | + sizeof(mm->saved_auxv) - (char *)elf_info); | |
| 280 | 282 | |
| 281 | 283 | /* And advance past the AT_NULL entry. */ |
| 282 | − ei_index += 2; | |
| 284 | + elf_info += 2; | |
| 283 | 285 | |
| 286 | + ei_index = elf_info - (elf_addr_t *)mm->saved_auxv; | |
| 284 | 287 | sp = STACK_ADD(p, ei_index); |
| 285 | 288 | |
| 286 | 289 | items = (argc + 1) + (envc + 1) + 1; |
| @@ -299,7 +302,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, · 12 unmodified lines | ||
| 299 | 302 | * Grow the stack manually; some architectures have a limit on how |
| 300 | 303 | * far ahead a user-space access may be in order to grow the stack. |
| 301 | 304 | */ |
| 302 | − vma = find_extend_vma(current->mm, bprm->p); | |
| 305 | + vma = find_extend_vma(mm, bprm->p); | |
| 303 | 306 | if (!vma) |
| 304 | 307 | return -EFAULT; |
| 305 | 308 | |
| @@ -308,7 +311,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, · 2 unmodified lines | ||
| 308 | 311 | return -EFAULT; |
| 309 | 312 | |
| 310 | 313 | /* Populate list of argv pointers back to argv strings. */ |
| 311 | − p = current->mm->arg_end = current->mm->arg_start; | |
| 314 | + p = mm->arg_end = mm->arg_start; | |
| 312 | 315 | while (argc-- > 0) { |
| 313 | 316 | size_t len; |
| 314 | 317 | if (__put_user((elf_addr_t)p, sp++)) |
| @@ -320,10 +323,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, · 5 unmodified lines | ||
| 320 | 323 | } |
| 321 | 324 | if (__put_user(0, sp++)) |
| 322 | 325 | return -EFAULT; |
| 323 | − current->mm->arg_end = p; | |
| 326 | + mm->arg_end = p; | |
| 324 | 327 | |
| 325 | 328 | /* Populate list of envp pointers back to envp strings. */ |
| 326 | − current->mm->env_end = current->mm->env_start = p; | |
| 329 | + mm->env_end = mm->env_start = p; | |
| 327 | 330 | while (envc-- > 0) { |
| 328 | 331 | size_t len; |
| 329 | 332 | if (__put_user((elf_addr_t)p, sp++)) |
| @@ -335,10 +338,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, · 5 unmodified lines | ||
| 335 | 338 | } |
| 336 | 339 | if (__put_user(0, sp++)) |
| 337 | 340 | return -EFAULT; |
| 338 | − current->mm->env_end = p; | |
| 341 | + mm->env_end = p; | |
| 339 | 342 | |
| 340 | 343 | /* Put the elf_info on the stack in the right place. */ |
| 341 | − if (copy_to_user(sp, elf_info, ei_index * sizeof(elf_addr_t))) | |
| 344 | + if (copy_to_user(sp, mm->saved_auxv, ei_index * sizeof(elf_addr_t))) | |
| 342 | 345 | return -EFAULT; |
| 343 | 346 | return 0; |
| 344 | 347 | } |
| @@ -689,15 +692,17 @@ static int load_elf_binary(struct linux_binprm *bprm) · 344 unmodified lines | ||
| 689 | 692 | int bss_prot = 0; |
| 690 | 693 | int retval, i; |
| 691 | 694 | unsigned long elf_entry; |
| 695 | + unsigned long e_entry; | |
| 692 | 696 | unsigned long interp_load_addr = 0; |
| 693 | 697 | unsigned long start_code, end_code, start_data, end_data; |
| 694 | 698 | unsigned long reloc_func_desc __maybe_unused = 0; |
| 695 | 699 | int executable_stack = EXSTACK_DEFAULT; |
| 700 | + struct elfhdr *elf_ex = (struct elfhdr *)bprm->buf; | |
| 696 | 701 | struct { |
| 697 | − struct elfhdr elf_ex; | |
| 698 | 702 | struct elfhdr interp_elf_ex; |
| 699 | 703 | } *loc; |
| 700 | 704 | struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE; |
| 705 | + struct mm_struct *mm; | |
| 701 | 706 | struct pt_regs *regs; |
| 702 | 707 | |
| 703 | 708 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); |
| @@ -705,30 +710,27 @@ static int load_elf_binary(struct linux_binprm *bprm) · 1 unmodified line | ||
| 705 | 710 | retval = -ENOMEM; |
| 706 | 711 | goto out_ret; |
| 707 | 712 | } |
| 708 | − | |
| 709 | − /* Get the exec-header */ | |
| 710 | − loc->elf_ex = *((struct elfhdr *)bprm->buf); | |
| 711 | 713 | |
| 712 | 714 | retval = -ENOEXEC; |
| 713 | 715 | /* First of all, some simple consistency checks */ |
| 714 | − if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0) | |
| 716 | + if (memcmp(elf_ex->e_ident, ELFMAG, SELFMAG) != 0) | |
| 715 | 717 | goto out; |
| 716 | 718 | |
| 717 | − if (loc->elf_ex.e_type != ET_EXEC && loc->elf_ex.e_type != ET_DYN) | |
| 719 | + if (elf_ex->e_type != ET_EXEC && elf_ex->e_type != ET_DYN) | |
| 718 | 720 | goto out; |
| 719 | − if (!elf_check_arch(&loc->elf_ex)) | |
| 721 | + if (!elf_check_arch(elf_ex)) | |
| 720 | 722 | goto out; |
| 721 | − if (elf_check_fdpic(&loc->elf_ex)) | |
| 723 | + if (elf_check_fdpic(elf_ex)) | |
| 722 | 724 | goto out; |
| 723 | 725 | if (!bprm->file->f_op->mmap) |
| 724 | 726 | goto out; |
| 725 | 727 | |
| 726 | − elf_phdata = load_elf_phdrs(&loc->elf_ex, bprm->file); | |
| 728 | + elf_phdata = load_elf_phdrs(elf_ex, bprm->file); | |
| 727 | 729 | if (!elf_phdata) |
| 728 | 730 | goto out; |
| 729 | 731 | |
| 730 | 732 | elf_ppnt = elf_phdata; |
| 731 | − for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { | |
| 733 | + for (i = 0; i < elf_ex->e_phnum; i++, elf_ppnt++) { | |
| 732 | 734 | char *elf_interpreter; |
| 733 | 735 | |
| 734 | 736 | if (elf_ppnt->p_type != PT_INTERP) |
| @@ -782,7 +784,7 @@ out_free_interp: · 47 unmodified lines | ||
| 782 | 784 | } |
| 783 | 785 | |
| 784 | 786 | elf_ppnt = elf_phdata; |
| 785 | − for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) | |
| 787 | + for (i = 0; i < elf_ex->e_phnum; i++, elf_ppnt++) | |
| 786 | 788 | switch (elf_ppnt->p_type) { |
| 787 | 789 | case PT_GNU_STACK: |
| 788 | 790 | if (elf_ppnt->p_flags & PF_X) |
| @@ -792,7 +794,7 @@ out_free_interp: · 3 unmodified lines | ||
| 792 | 794 | break; |
| 793 | 795 | |
| 794 | 796 | case PT_LOPROC ... PT_HIPROC: |
| 795 | − retval = arch_elf_pt_proc(&loc->elf_ex, elf_ppnt, | |
| 797 | + retval = arch_elf_pt_proc(elf_ex, elf_ppnt, | |
| 796 | 798 | bprm->file, false, |
| 797 | 799 | &arch_state); |
| 798 | 800 | if (retval) |
| @@ -836,7 +838,7 @@ out_free_interp: · 37 unmodified lines | ||
| 836 | 838 | * still possible to return an error to the code that invoked |
| 837 | 839 | * the exec syscall. |
| 838 | 840 | */ |
| 839 | − retval = arch_check_elf(&loc->elf_ex, | |
| 841 | + retval = arch_check_elf(elf_ex, | |
| 840 | 842 | !!interpreter, &loc->interp_elf_ex, |
| 841 | 843 | &arch_state); |
| 842 | 844 | if (retval) |
| @@ -849,8 +851,8 @@ out_free_interp: · 6 unmodified lines | ||
| 849 | 851 | |
| 850 | 852 | /* Do this immediately, since STACK_TOP as used in setup_arg_pages |
| 851 | 853 | may depend on the personality. */ |
| 852 | − SET_PERSONALITY2(loc->elf_ex, &arch_state); | |
| 853 | − if (elf_read_implies_exec(loc->elf_ex, executable_stack)) | |
| 854 | + SET_PERSONALITY2(*elf_ex, &arch_state); | |
| 855 | + if (elf_read_implies_exec(*elf_ex, executable_stack)) | |
| 854 | 856 | current->personality |= READ_IMPLIES_EXEC; |
| 855 | 857 | |
| 856 | 858 | if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) |
| @@ -877,7 +879,7 @@ out_free_interp: · 20 unmodified lines | ||
| 877 | 879 | /* Now we do a little grungy work by mmapping the ELF image into |
| 878 | 880 | the correct location in memory. */ |
| 879 | 881 | for(i = 0, elf_ppnt = elf_phdata; |
| 880 | − i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { | |
| 882 | + i < elf_ex->e_phnum; i++, elf_ppnt++) { | |
| 881 | 883 | int elf_prot, elf_flags; |
| 882 | 884 | unsigned long k, vaddr; |
| 883 | 885 | unsigned long total_size = 0; |
| @@ -921,9 +923,9 @@ out_free_interp: · 37 unmodified lines | ||
| 921 | 923 | * If we are loading ET_EXEC or we have already performed |
| 922 | 924 | * the ET_DYN load_addr calculations, proceed normally. |
| 923 | 925 | */ |
| 924 | − if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) { | |
| 926 | + if (elf_ex->e_type == ET_EXEC || load_addr_set) { | |
| 925 | 927 | elf_flags |= MAP_FIXED; |
| 926 | − } else if (loc->elf_ex.e_type == ET_DYN) { | |
| 928 | + } else if (elf_ex->e_type == ET_DYN) { | |
| 927 | 929 | /* |
| 928 | 930 | * This logic is run once for the first LOAD Program |
| 929 | 931 | * Header for ET_DYN binaries to calculate the |
| @@ -972,7 +974,7 @@ out_free_interp: · 42 unmodified lines | ||
| 972 | 974 | load_bias = ELF_PAGESTART(load_bias - vaddr); |
| 973 | 975 | |
| 974 | 976 | total_size = total_mapping_size(elf_phdata, |
| 975 | − loc->elf_ex.e_phnum); | |
| 977 | + elf_ex->e_phnum); | |
| 976 | 978 | if (!total_size) { |
| 977 | 979 | retval = -EINVAL; |
| 978 | 980 | goto out_free_dentry; |
| @@ -990,7 +992,7 @@ out_free_interp: · 11 unmodified lines | ||
| 990 | 992 | if (!load_addr_set) { |
| 991 | 993 | load_addr_set = 1; |
| 992 | 994 | load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset); |
| 993 | − if (loc->elf_ex.e_type == ET_DYN) { | |
| 995 | + if (elf_ex->e_type == ET_DYN) { | |
| 994 | 996 | load_bias += error - |
| 995 | 997 | ELF_PAGESTART(load_bias + vaddr); |
| 996 | 998 | load_addr += load_bias; |
| @@ -998,7 +1000,7 @@ out_free_interp: · 1 unmodified line | ||
| 998 | 1000 | } |
| 999 | 1001 | } |
| 1000 | 1002 | k = elf_ppnt->p_vaddr; |
| 1001 | − if (k < start_code) | |
| 1003 | + if ((elf_ppnt->p_flags & PF_X) && k < start_code) | |
| 1002 | 1004 | start_code = k; |
| 1003 | 1005 | if (start_data < k) |
| 1004 | 1006 | start_data = k; |
| @@ -1031,7 +1033,7 @@ out_free_interp: · 26 unmodified lines | ||
| 1031 | 1033 | } |
| 1032 | 1034 | } |
| 1033 | 1035 | |
| 1034 | − loc->elf_ex.e_entry += load_bias; | |
| 1036 | + e_entry = elf_ex->e_entry + load_bias; | |
| 1035 | 1037 | elf_bss += load_bias; |
| 1036 | 1038 | elf_brk += load_bias; |
| 1037 | 1039 | start_code += load_bias; |
| @@ -1074,7 +1076,7 @@ out_free_interp: · 36 unmodified lines | ||
| 1074 | 1076 | allow_write_access(interpreter); |
| 1075 | 1077 | fput(interpreter); |
| 1076 | 1078 | } else { |
| 1077 | − elf_entry = loc->elf_ex.e_entry; | |
| 1079 | + elf_entry = e_entry; | |
| 1078 | 1080 | if (BAD_ADDR(elf_entry)) { |
| 1079 | 1081 | retval = -EINVAL; |
| 1080 | 1082 | goto out_free_dentry; |
| @@ -1092,15 +1094,17 @@ out_free_interp: · 11 unmodified lines | ||
| 1092 | 1094 | goto out; |
| 1093 | 1095 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ |
| 1094 | 1096 | |
| 1095 | − retval = create_elf_tables(bprm, &loc->elf_ex, | |
| 1096 | − load_addr, interp_load_addr); | |
| 1097 | + retval = create_elf_tables(bprm, elf_ex, | |
| 1098 | + load_addr, interp_load_addr, e_entry); | |
| 1097 | 1099 | if (retval < 0) |
| 1098 | 1100 | goto out; |
| 1099 | − current->mm->end_code = end_code; | |
| 1100 | − current->mm->start_code = start_code; | |
| 1101 | − current->mm->start_data = start_data; | |
| 1102 | − current->mm->end_data = end_data; | |
| 1103 | − current->mm->start_stack = bprm->p; | |
| 1101 | + | |
| 1102 | + mm = current->mm; | |
| 1103 | + mm->end_code = end_code; | |
| 1104 | + mm->start_code = start_code; | |
| 1105 | + mm->start_data = start_data; | |
| 1106 | + mm->end_data = end_data; | |
| 1107 | + mm->start_stack = bprm->p; | |
| 1104 | 1108 | |
| 1105 | 1109 | if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) { |
| 1106 | 1110 | /* |
| @@ -1111,12 +1115,11 @@ out_free_interp: · 4 unmodified lines | ||
| 1111 | 1115 | * growing down), and into the unused ELF_ET_DYN_BASE region. |
| 1112 | 1116 | */ |
| 1113 | 1117 | if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) && |
| 1114 | − loc->elf_ex.e_type == ET_DYN && !interpreter) | |
| 1115 | − current->mm->brk = current->mm->start_brk = | |
| 1116 | − ELF_ET_DYN_BASE; | |
| 1118 | + elf_ex->e_type == ET_DYN && !interpreter) { | |
| 1119 | + mm->brk = mm->start_brk = ELF_ET_DYN_BASE; | |
| 1120 | + } | |
| 1117 | 1121 | |
| 1118 | − current->mm->brk = current->mm->start_brk = | |
| 1119 | − arch_randomize_brk(current->mm); | |
| 1122 | + mm->brk = mm->start_brk = arch_randomize_brk(mm); | |
| 1120 | 1123 | #ifdef compat_brk_randomized |
| 1121 | 1124 | current->brk_randomized = 1; |
| 1122 | 1125 | #endif |
| @@ -1574,6 +1577,7 @@ static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata, · 451 unmodified lines | ||
| 1574 | 1577 | */ |
| 1575 | 1578 | static int fill_files_note(struct memelfnote *note) |
| 1576 | 1579 | { |
| 1580 | + struct mm_struct *mm = current->mm; | |
| 1577 | 1581 | struct vm_area_struct *vma; |
| 1578 | 1582 | unsigned count, size, names_ofs, remaining, n; |
| 1579 | 1583 | user_long_t *data; |
| @@ -1581,7 +1585,7 @@ static int fill_files_note(struct memelfnote *note) · 1 unmodified line | ||
| 1581 | 1585 | char *name_base, *name_curpos; |
| 1582 | 1586 | |
| 1583 | 1587 | /* *Estimated* file count and total data size needed */ |
| 1584 | − count = current->mm->map_count; | |
| 1588 | + count = mm->map_count; | |
| 1585 | 1589 | if (count > UINT_MAX / 64) |
| 1586 | 1590 | return -EINVAL; |
| 1587 | 1591 | size = count * 64; |
| @@ -1591,6 +1595,10 @@ static int fill_files_note(struct memelfnote *note) · 3 unmodified lines | ||
| 1591 | 1595 | if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */ |
| 1592 | 1596 | return -EINVAL; |
| 1593 | 1597 | size = round_up(size, PAGE_SIZE); |
| 1598 | + /* | |
| 1599 | + * "size" can be 0 here legitimately. | |
| 1600 | + * Let it ENOMEM and omit NT_FILE section which will be empty anyway. | |
| 1601 | + */ | |
| 1594 | 1602 | data = kvmalloc(size, GFP_KERNEL); |
| 1595 | 1603 | if (ZERO_OR_NULL_PTR(data)) |
| 1596 | 1604 | return -ENOMEM; |
| @@ -1599,7 +1607,7 @@ static int fill_files_note(struct memelfnote *note) · 2 unmodified lines | ||
| 1599 | 1607 | name_base = name_curpos = ((char *)data) + names_ofs; |
| 1600 | 1608 | remaining = size - names_ofs; |
| 1601 | 1609 | count = 0; |
| 1602 | − for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { | |
| 1610 | + for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) { | |
| 1603 | 1611 | struct file *file; |
| 1604 | 1612 | const char *filename; |
| 1605 | 1613 | |
| @@ -1633,10 +1641,10 @@ static int fill_files_note(struct memelfnote *note) · 27 unmodified lines | ||
| 1633 | 1641 | data[0] = count; |
| 1634 | 1642 | data[1] = PAGE_SIZE; |
| 1635 | 1643 | /* |
| 1636 | − * Count usually is less than current->mm->map_count, | |
| 1644 | + * Count usually is less than mm->map_count, | |
| 1637 | 1645 | * we need to move filenames down. |
| 1638 | 1646 | */ |
| 1639 | − n = current->mm->map_count - count; | |
| 1647 | + n = mm->map_count - count; | |
| 1640 | 1648 | if (n != 0) { |
| 1641 | 1649 | unsigned shift_bytes = n * 3 * sizeof(data[0]); |
| 1642 | 1650 | memmove(name_base - shift_bytes, name_base, |
| @@ -2182,7 +2190,7 @@ static int elf_core_dump(struct coredump_params *cprm) · 539 unmodified lines | ||
| 2182 | 2190 | int segs, i; |
| 2183 | 2191 | size_t vma_data_size = 0; |
| 2184 | 2192 | struct vm_area_struct *vma, *gate_vma; |
| 2185 | − struct elfhdr *elf = NULL; | |
| 2193 | + struct elfhdr elf; | |
| 2186 | 2194 | loff_t offset = 0, dataoff; |
| 2187 | 2195 | struct elf_note_info info = { }; |
| 2188 | 2196 | struct elf_phdr *phdr4note = NULL; |
| @@ -2203,10 +2211,6 @@ static int elf_core_dump(struct coredump_params *cprm) · 14 unmodified lines | ||
| 2203 | 2211 | * exists while dumping the mm->vm_next areas to the core file. |
| 2204 | 2212 | */ |
| 2205 | 2213 | |
| 2206 | − /* alloc memory for large data structures: too large to be on stack */ | |
| 2207 | − elf = kmalloc(sizeof(*elf), GFP_KERNEL); | |
| 2208 | − if (!elf) | |
| 2209 | − goto out; | |
| 2210 | 2214 | /* |
| 2211 | 2215 | * The number of segs are recored into ELF header as 16bit value. |
| 2212 | 2216 | * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here. |
| @@ -2230,7 +2234,7 @@ static int elf_core_dump(struct coredump_params *cprm) · 17 unmodified lines | ||
| 2230 | 2234 | * Collect all the non-memory information about the process for the |
| 2231 | 2235 | * notes. This also sets up the file header. |
| 2232 | 2236 | */ |
| 2233 | − if (!fill_note_info(elf, e_phnum, &info, cprm->siginfo, cprm->regs)) | |
| 2237 | + if (!fill_note_info(&elf, e_phnum, &info, cprm->siginfo, cprm->regs)) | |
| 2234 | 2238 | goto cleanup; |
| 2235 | 2239 | |
| 2236 | 2240 | has_dumped = 1; |
| @@ -2238,7 +2242,7 @@ static int elf_core_dump(struct coredump_params *cprm) · 1 unmodified line | ||
| 2238 | 2242 | fs = get_fs(); |
| 2239 | 2243 | set_fs(KERNEL_DS); |
| 2240 | 2244 | |
| 2241 | − offset += sizeof(*elf); /* Elf header */ | |
| 2245 | + offset += sizeof(elf); /* Elf header */ | |
| 2242 | 2246 | offset += segs * sizeof(struct elf_phdr); /* Program headers */ |
| 2243 | 2247 | |
| 2244 | 2248 | /* Write notes phdr entry */ |
| @@ -2257,11 +2261,13 @@ static int elf_core_dump(struct coredump_params *cprm) · 12 unmodified lines | ||
| 2257 | 2261 | |
| 2258 | 2262 | dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); |
| 2259 | 2263 | |
| 2260 | − if (segs - 1 > ULONG_MAX / sizeof(*vma_filesz)) | |
| 2261 | − goto end_coredump; | |
| 2264 | + /* | |
| 2265 | + * Zero vma process will get ZERO_SIZE_PTR here. | |
| 2266 | + * Let coredump continue for register state at least. | |
| 2267 | + */ | |
| 2262 | 2268 | vma_filesz = kvmalloc(array_size(sizeof(*vma_filesz), (segs - 1)), |
| 2263 | 2269 | GFP_KERNEL); |
| 2264 | − if (ZERO_OR_NULL_PTR(vma_filesz)) | |
| 2270 | + if (!vma_filesz) | |
| 2265 | 2271 | goto end_coredump; |
| 2266 | 2272 | |
| 2267 | 2273 | for (i = 0, vma = first_vma(current, gate_vma); vma != NULL; |
| @@ -2281,12 +2287,12 @@ static int elf_core_dump(struct coredump_params *cprm) · 13 unmodified lines | ||
| 2281 | 2287 | shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL); |
| 2282 | 2288 | if (!shdr4extnum) |
| 2283 | 2289 | goto end_coredump; |
| 2284 | − fill_extnum_info(elf, shdr4extnum, e_shoff, segs); | |
| 2290 | + fill_extnum_info(&elf, shdr4extnum, e_shoff, segs); | |
| 2285 | 2291 | } |
| 2286 | 2292 | |
| 2287 | 2293 | offset = dataoff; |
| 2288 | 2294 | |
| 2289 | − if (!dump_emit(cprm, elf, sizeof(*elf))) | |
| 2295 | + if (!dump_emit(cprm, &elf, sizeof(elf))) | |
| 2290 | 2296 | goto end_coredump; |
| 2291 | 2297 | |
| 2292 | 2298 | if (!dump_emit(cprm, phdr4note, sizeof(*phdr4note))) |
| @@ -2370,8 +2376,6 @@ cleanup: · 77 unmodified lines | ||
| 2370 | 2376 | kfree(shdr4extnum); |
| 2371 | 2377 | kvfree(vma_filesz); |
| 2372 | 2378 | kfree(phdr4note); |
| 2373 | − kfree(elf); | |
| 2374 | −out: | |
| 2375 | 2379 | return has_dumped; |
| 2376 | 2380 | } |
| 2377 | 2381 | |
| @@ -1290,7 +1290,7 @@ int btrfs_decompress_buf2page(const char *buf, unsigned long buf_start, · 1289 unmodified lines | ||
| 1290 | 1290 | /* copy bytes from the working buffer into the pages */ |
| 1291 | 1291 | while (working_bytes > 0) { |
| 1292 | 1292 | bytes = min_t(unsigned long, bvec.bv_len, |
| 1293 | − PAGE_SIZE - buf_offset); | |
| 1293 | + PAGE_SIZE - (buf_offset % PAGE_SIZE)); | |
| 1294 | 1294 | bytes = min(bytes, working_bytes); |
| 1295 | 1295 | |
| 1296 | 1296 | kaddr = kmap_atomic(bvec.bv_page); |
| @@ -20,9 +20,13 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/refcount.h> |
| 21 | 21 | #include "compression.h" |
| 22 | 22 | |
| 23 | +/* workspace buffer size for s390 zlib hardware support */ | |
| 24 | +#define ZLIB_DFLTCC_BUF_SIZE (4 * PAGE_SIZE) | |
| 25 | + | |
| 23 | 26 | struct workspace { |
| 24 | 27 | z_stream strm; |
| 25 | 28 | char *buf; |
| 29 | + unsigned int buf_size; | |
| 26 | 30 | struct list_head list; |
| 27 | 31 | int level; |
| 28 | 32 | }; |
| @@ -61,7 +65,21 @@ struct list_head *zlib_alloc_workspace(unsigned int level) · 32 unmodified lines | ||
| 61 | 65 | zlib_inflate_workspacesize()); |
| 62 | 66 | workspace->strm.workspace = kvmalloc(workspacesize, GFP_KERNEL); |
| 63 | 67 | workspace->level = level; |
| 64 | − workspace->buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
| 68 | + workspace->buf = NULL; | |
| 69 | + /* | |
| 70 | + * In case of s390 zlib hardware support, allocate lager workspace | |
| 71 | + * buffer. If allocator fails, fall back to a single page buffer. | |
| 72 | + */ | |
| 73 | + if (zlib_deflate_dfltcc_enabled()) { | |
| 74 | + workspace->buf = kmalloc(ZLIB_DFLTCC_BUF_SIZE, | |
| 75 | + __GFP_NOMEMALLOC | __GFP_NORETRY | | |
| 76 | + __GFP_NOWARN | GFP_NOIO); | |
| 77 | + workspace->buf_size = ZLIB_DFLTCC_BUF_SIZE; | |
| 78 | + } | |
| 79 | + if (!workspace->buf) { | |
| 80 | + workspace->buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
| 81 | + workspace->buf_size = PAGE_SIZE; | |
| 82 | + } | |
| 65 | 83 | if (!workspace->strm.workspace || !workspace->buf) |
| 66 | 84 | goto fail; |
| 67 | 85 | |
| @@ -85,6 +103,7 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 17 unmodified lines | ||
| 85 | 103 | struct page *in_page = NULL; |
| 86 | 104 | struct page *out_page = NULL; |
| 87 | 105 | unsigned long bytes_left; |
| 106 | + unsigned int in_buf_pages; | |
| 88 | 107 | unsigned long len = *total_out; |
| 89 | 108 | unsigned long nr_dest_pages = *out_pages; |
| 90 | 109 | const unsigned long max_out = nr_dest_pages * PAGE_SIZE; |
| @@ -102,9 +121,6 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 11 unmodified lines | ||
| 102 | 121 | workspace->strm.total_in = 0; |
| 103 | 122 | workspace->strm.total_out = 0; |
| 104 | 123 | |
| 105 | − in_page = find_get_page(mapping, start >> PAGE_SHIFT); | |
| 106 | − data_in = kmap(in_page); | |
| 107 | − | |
| 108 | 124 | out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); |
| 109 | 125 | if (out_page == NULL) { |
| 110 | 126 | ret = -ENOMEM; |
| @@ -114,12 +130,51 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 3 unmodified lines | ||
| 114 | 130 | pages[0] = out_page; |
| 115 | 131 | nr_pages = 1; |
| 116 | 132 | |
| 117 | − workspace->strm.next_in = data_in; | |
| 133 | + workspace->strm.next_in = workspace->buf; | |
| 134 | + workspace->strm.avail_in = 0; | |
| 118 | 135 | workspace->strm.next_out = cpage_out; |
| 119 | 136 | workspace->strm.avail_out = PAGE_SIZE; |
| 120 | − workspace->strm.avail_in = min(len, PAGE_SIZE); | |
| 121 | 137 | |
| 122 | 138 | while (workspace->strm.total_in < len) { |
| 139 | + /* | |
| 140 | + * Get next input pages and copy the contents to | |
| 141 | + * the workspace buffer if required. | |
| 142 | + */ | |
| 143 | + if (workspace->strm.avail_in == 0) { | |
| 144 | + bytes_left = len - workspace->strm.total_in; | |
| 145 | + in_buf_pages = min(DIV_ROUND_UP(bytes_left, PAGE_SIZE), | |
| 146 | + workspace->buf_size / PAGE_SIZE); | |
| 147 | + if (in_buf_pages > 1) { | |
| 148 | + int i; | |
| 149 | + | |
| 150 | + for (i = 0; i < in_buf_pages; i++) { | |
| 151 | + if (in_page) { | |
| 152 | + kunmap(in_page); | |
| 153 | + put_page(in_page); | |
| 154 | + } | |
| 155 | + in_page = find_get_page(mapping, | |
| 156 | + start >> PAGE_SHIFT); | |
| 157 | + data_in = kmap(in_page); | |
| 158 | + memcpy(workspace->buf + i * PAGE_SIZE, | |
| 159 | + data_in, PAGE_SIZE); | |
| 160 | + start += PAGE_SIZE; | |
| 161 | + } | |
| 162 | + workspace->strm.next_in = workspace->buf; | |
| 163 | + } else { | |
| 164 | + if (in_page) { | |
| 165 | + kunmap(in_page); | |
| 166 | + put_page(in_page); | |
| 167 | + } | |
| 168 | + in_page = find_get_page(mapping, | |
| 169 | + start >> PAGE_SHIFT); | |
| 170 | + data_in = kmap(in_page); | |
| 171 | + start += PAGE_SIZE; | |
| 172 | + workspace->strm.next_in = data_in; | |
| 173 | + } | |
| 174 | + workspace->strm.avail_in = min(bytes_left, | |
| 175 | + (unsigned long) workspace->buf_size); | |
| 176 | + } | |
| 177 | + | |
| 123 | 178 | ret = zlib_deflate(&workspace->strm, Z_SYNC_FLUSH); |
| 124 | 179 | if (ret != Z_OK) { |
| 125 | 180 | pr_debug("BTRFS: deflate in loop returned %d\n", |
| @@ -161,33 +216,43 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 35 unmodified lines | ||
| 161 | 216 | /* we're all done */ |
| 162 | 217 | if (workspace->strm.total_in >= len) |
| 163 | 218 | break; |
| 164 | − | |
| 165 | − /* we've read in a full page, get a new one */ | |
| 166 | − if (workspace->strm.avail_in == 0) { | |
| 167 | − if (workspace->strm.total_out > max_out) | |
| 168 | − break; | |
| 169 | − | |
| 170 | − bytes_left = len - workspace->strm.total_in; | |
| 171 | − kunmap(in_page); | |
| 172 | − put_page(in_page); | |
| 173 | − | |
| 174 | − start += PAGE_SIZE; | |
| 175 | − in_page = find_get_page(mapping, | |
| 176 | − start >> PAGE_SHIFT); | |
| 177 | − data_in = kmap(in_page); | |
| 178 | − workspace->strm.avail_in = min(bytes_left, | |
| 179 | − PAGE_SIZE); | |
| 180 | − workspace->strm.next_in = data_in; | |
| 181 | − } | |
| 219 | + if (workspace->strm.total_out > max_out) | |
| 220 | + break; | |
| 182 | 221 | } |
| 183 | 222 | workspace->strm.avail_in = 0; |
| 184 | − ret = zlib_deflate(&workspace->strm, Z_FINISH); | |
| 185 | − zlib_deflateEnd(&workspace->strm); | |
| 186 | − | |
| 187 | − if (ret != Z_STREAM_END) { | |
| 188 | − ret = -EIO; | |
| 189 | − goto out; | |
| 223 | + /* | |
| 224 | + * Call deflate with Z_FINISH flush parameter providing more output | |
| 225 | + * space but no more input data, until it returns with Z_STREAM_END. | |
| 226 | + */ | |
| 227 | + while (ret != Z_STREAM_END) { | |
| 228 | + ret = zlib_deflate(&workspace->strm, Z_FINISH); | |
| 229 | + if (ret == Z_STREAM_END) | |
| 230 | + break; | |
| 231 | + if (ret != Z_OK && ret != Z_BUF_ERROR) { | |
| 232 | + zlib_deflateEnd(&workspace->strm); | |
| 233 | + ret = -EIO; | |
| 234 | + goto out; | |
| 235 | + } else if (workspace->strm.avail_out == 0) { | |
| 236 | + /* get another page for the stream end */ | |
| 237 | + kunmap(out_page); | |
| 238 | + if (nr_pages == nr_dest_pages) { | |
| 239 | + out_page = NULL; | |
| 240 | + ret = -E2BIG; | |
| 241 | + goto out; | |
| 242 | + } | |
| 243 | + out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); | |
| 244 | + if (out_page == NULL) { | |
| 245 | + ret = -ENOMEM; | |
| 246 | + goto out; | |
| 247 | + } | |
| 248 | + cpage_out = kmap(out_page); | |
| 249 | + pages[nr_pages] = out_page; | |
| 250 | + nr_pages++; | |
| 251 | + workspace->strm.avail_out = PAGE_SIZE; | |
| 252 | + workspace->strm.next_out = cpage_out; | |
| 253 | + } | |
| 190 | 254 | } |
| 255 | + zlib_deflateEnd(&workspace->strm); | |
| 191 | 256 | |
| 192 | 257 | if (workspace->strm.total_out >= workspace->strm.total_in) { |
| 193 | 258 | ret = -E2BIG; |
| @@ -231,7 +296,7 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 37 unmodified lines | ||
| 231 | 296 | |
| 232 | 297 | workspace->strm.total_out = 0; |
| 233 | 298 | workspace->strm.next_out = workspace->buf; |
| 234 | − workspace->strm.avail_out = PAGE_SIZE; | |
| 299 | + workspace->strm.avail_out = workspace->buf_size; | |
| 235 | 300 | |
| 236 | 301 | /* If it's deflate, and it's got no preset dictionary, then |
| 237 | 302 | we can tell zlib to skip the adler32 check. */ |
| @@ -270,7 +335,7 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 32 unmodified lines | ||
| 270 | 335 | } |
| 271 | 336 | |
| 272 | 337 | workspace->strm.next_out = workspace->buf; |
| 273 | − workspace->strm.avail_out = PAGE_SIZE; | |
| 338 | + workspace->strm.avail_out = workspace->buf_size; | |
| 274 | 339 | |
| 275 | 340 | if (workspace->strm.avail_in == 0) { |
| 276 | 341 | unsigned long tmp; |
| @@ -320,7 +385,7 @@ int zlib_decompress(struct list_head *ws, unsigned char *data_in, · 43 unmodified lines | ||
| 320 | 385 | workspace->strm.total_in = 0; |
| 321 | 386 | |
| 322 | 387 | workspace->strm.next_out = workspace->buf; |
| 323 | − workspace->strm.avail_out = PAGE_SIZE; | |
| 388 | + workspace->strm.avail_out = workspace->buf_size; | |
| 324 | 389 | workspace->strm.total_out = 0; |
| 325 | 390 | /* If it's deflate, and it's got no preset dictionary, then |
| 326 | 391 | we can tell zlib to skip the adler32 check. */ |
| @@ -364,7 +429,7 @@ int zlib_decompress(struct list_head *ws, unsigned char *data_in, · 37 unmodified lines | ||
| 364 | 429 | buf_offset = 0; |
| 365 | 430 | |
| 366 | 431 | bytes = min(PAGE_SIZE - pg_offset, |
| 367 | − PAGE_SIZE - buf_offset); | |
| 432 | + PAGE_SIZE - (buf_offset % PAGE_SIZE)); | |
| 368 | 433 | bytes = min(bytes, bytes_left); |
| 369 | 434 | |
| 370 | 435 | kaddr = kmap_atomic(dest_page); |
| @@ -375,7 +440,7 @@ int zlib_decompress(struct list_head *ws, unsigned char *data_in, · 4 unmodified lines | ||
| 375 | 440 | bytes_left -= bytes; |
| 376 | 441 | next: |
| 377 | 442 | workspace->strm.next_out = workspace->buf; |
| 378 | − workspace->strm.avail_out = PAGE_SIZE; | |
| 443 | + workspace->strm.avail_out = workspace->buf_size; | |
| 379 | 444 | } |
| 380 | 445 | |
| 381 | 446 | if (ret != Z_STREAM_END && bytes_left != 0) |
| @@ -760,6 +760,11 @@ int setup_arg_pages(struct linux_binprm *bprm, · 759 unmodified lines | ||
| 760 | 760 | goto out_unlock; |
| 761 | 761 | BUG_ON(prev != vma); |
| 762 | 762 | |
| 763 | + if (unlikely(vm_flags & VM_EXEC)) { | |
| 764 | + pr_warn_once("process '%pD4' started with executable stack\n", | |
| 765 | + bprm->file); | |
| 766 | + } | |
| 767 | + | |
| 763 | 768 | /* Move stack pages down in memory. */ |
| 764 | 769 | if (stack_shift) { |
| 765 | 770 | ret = shift_arg_pages(vma, stack_shift); |
| @@ -2063,7 +2063,7 @@ void wb_workfn(struct work_struct *work) · 2062 unmodified lines | ||
| 2063 | 2063 | struct bdi_writeback, dwork); |
| 2064 | 2064 | long pages_written; |
| 2065 | 2065 | |
| 2066 | − set_worker_desc("flush-%s", dev_name(wb->bdi->dev)); | |
| 2066 | + set_worker_desc("flush-%s", bdi_dev_name(wb->bdi)); | |
| 2067 | 2067 | current->flags |= PF_SWAPWRITE; |
| 2068 | 2068 | |
| 2069 | 2069 | if (likely(!current_is_workqueue_rescuer() || |
| @@ -6005,7 +6005,7 @@ static int io_sqe_buffer_unregister(struct io_ring_ctx *ctx) · 6004 unmodified lines | ||
| 6005 | 6005 | struct io_mapped_ubuf *imu = &ctx->user_bufs[i]; |
| 6006 | 6006 | |
| 6007 | 6007 | for (j = 0; j < imu->nr_bvecs; j++) |
| 6008 | − put_user_page(imu->bvec[j].bv_page); | |
| 6008 | + unpin_user_page(imu->bvec[j].bv_page); | |
| 6009 | 6009 | |
| 6010 | 6010 | if (ctx->account_mem) |
| 6011 | 6011 | io_unaccount_mem(ctx->user, imu->nr_bvecs); |
| @@ -6126,7 +6126,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, void __user *arg, · 114 unmodified lines | ||
| 6126 | 6126 | |
| 6127 | 6127 | ret = 0; |
| 6128 | 6128 | down_read(¤t->mm->mmap_sem); |
| 6129 | − pret = get_user_pages(ubuf, nr_pages, | |
| 6129 | + pret = pin_user_pages(ubuf, nr_pages, | |
| 6130 | 6130 | FOLL_WRITE | FOLL_LONGTERM, |
| 6131 | 6131 | pages, vmas); |
| 6132 | 6132 | if (pret == nr_pages) { |
| @@ -6150,7 +6150,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, void __user *arg, · 17 unmodified lines | ||
| 6150 | 6150 | * release any pages we did get |
| 6151 | 6151 | */ |
| 6152 | 6152 | if (pret > 0) |
| 6153 | − put_user_pages(pages, pret); | |
| 6153 | + unpin_user_pages(pages, pret); | |
| 6154 | 6154 | if (ctx->account_mem) |
| 6155 | 6155 | io_unaccount_mem(ctx->user, nr_pages); |
| 6156 | 6156 | kvfree(imu->bvec); |
| @@ -73,7 +73,7 @@ static void o2quo_fence_self(void) · 72 unmodified lines | ||
| 73 | 73 | "system by restarting ***\n"); |
| 74 | 74 | emergency_restart(); |
| 75 | 75 | break; |
| 76 | − }; | |
| 76 | + } | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | /* Indicate that a timeout occurred on a heartbeat region write. The |
| @@ -1,6 +1,4 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | −ccflags-y := -I $(srctree)/$(src)/.. | |
| 3 | − | |
| 4 | 2 | obj-$(CONFIG_OCFS2_FS_O2CB) += ocfs2_dlm.o |
| 5 | 3 | |
| 6 | 4 | ocfs2_dlm-objs := dlmdomain.o dlmdebug.o dlmthread.o dlmrecovery.o \ |
| @@ -23,15 +23,15 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/spinlock.h> |
| 24 | 24 | |
| 25 | 25 | |
| 26 | −#include "cluster/heartbeat.h" | |
| 27 | −#include "cluster/nodemanager.h" | |
| 28 | −#include "cluster/tcp.h" | |
| 26 | +#include "../cluster/heartbeat.h" | |
| 27 | +#include "../cluster/nodemanager.h" | |
| 28 | +#include "../cluster/tcp.h" | |
| 29 | 29 | |
| 30 | 30 | #include "dlmapi.h" |
| 31 | 31 | #include "dlmcommon.h" |
| 32 | 32 | |
| 33 | 33 | #define MLOG_MASK_PREFIX ML_DLM |
| 34 | −#include "cluster/masklog.h" | |
| 34 | +#include "../cluster/masklog.h" | |
| 35 | 35 | |
| 36 | 36 | static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, |
| 37 | 37 | struct dlm_lock *lock); |
| @@ -688,10 +688,6 @@ struct dlm_begin_reco · 687 unmodified lines | ||
| 688 | 688 | __be32 pad2; |
| 689 | 689 | }; |
| 690 | 690 | |
| 691 | − | |
| 692 | −#define BITS_PER_BYTE 8 | |
| 693 | −#define BITS_TO_BYTES(bits) (((bits)+BITS_PER_BYTE-1)/BITS_PER_BYTE) | |
| 694 | − | |
| 695 | 691 | struct dlm_query_join_request |
| 696 | 692 | { |
| 697 | 693 | u8 node_idx; |
| @@ -23,9 +23,9 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/spinlock.h> |
| 24 | 24 | |
| 25 | 25 | |
| 26 | −#include "cluster/heartbeat.h" | |
| 27 | −#include "cluster/nodemanager.h" | |
| 28 | −#include "cluster/tcp.h" | |
| 26 | +#include "../cluster/heartbeat.h" | |
| 27 | +#include "../cluster/nodemanager.h" | |
| 28 | +#include "../cluster/tcp.h" | |
| 29 | 29 | |
| 30 | 30 | #include "dlmapi.h" |
| 31 | 31 | #include "dlmcommon.h" |
| @@ -33,7 +33,7 @@ · 1 unmodified line | ||
| 33 | 33 | #include "dlmconvert.h" |
| 34 | 34 | |
| 35 | 35 | #define MLOG_MASK_PREFIX ML_DLM |
| 36 | −#include "cluster/masklog.h" | |
| 36 | +#include "../cluster/masklog.h" | |
| 37 | 37 | |
| 38 | 38 | /* NOTE: __dlmconvert_master is the only function in here that |
| 39 | 39 | * needs a spinlock held on entry (res->spinlock) and it is the |
| @@ -17,9 +17,9 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/debugfs.h> |
| 18 | 18 | #include <linux/export.h> |
| 19 | 19 | |
| 20 | −#include "cluster/heartbeat.h" | |
| 21 | −#include "cluster/nodemanager.h" | |
| 22 | −#include "cluster/tcp.h" | |
| 20 | +#include "../cluster/heartbeat.h" | |
| 21 | +#include "../cluster/nodemanager.h" | |
| 22 | +#include "../cluster/tcp.h" | |
| 23 | 23 | |
| 24 | 24 | #include "dlmapi.h" |
| 25 | 25 | #include "dlmcommon.h" |
| @@ -27,7 +27,7 @@ · 1 unmodified line | ||
| 27 | 27 | #include "dlmdebug.h" |
| 28 | 28 | |
| 29 | 29 | #define MLOG_MASK_PREFIX ML_DLM |
| 30 | −#include "cluster/masklog.h" | |
| 30 | +#include "../cluster/masklog.h" | |
| 31 | 31 | |
| 32 | 32 | static int stringify_lockname(const char *lockname, int locklen, char *buf, |
| 33 | 33 | int len); |
| @@ -20,9 +20,9 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/debugfs.h> |
| 21 | 21 | #include <linux/sched/signal.h> |
| 22 | 22 | |
| 23 | −#include "cluster/heartbeat.h" | |
| 24 | −#include "cluster/nodemanager.h" | |
| 25 | −#include "cluster/tcp.h" | |
| 23 | +#include "../cluster/heartbeat.h" | |
| 24 | +#include "../cluster/nodemanager.h" | |
| 25 | +#include "../cluster/tcp.h" | |
| 26 | 26 | |
| 27 | 27 | #include "dlmapi.h" |
| 28 | 28 | #include "dlmcommon.h" |
| @@ -30,7 +30,7 @@ · 1 unmodified line | ||
| 30 | 30 | #include "dlmdebug.h" |
| 31 | 31 | |
| 32 | 32 | #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_DOMAIN) |
| 33 | −#include "cluster/masklog.h" | |
| 33 | +#include "../cluster/masklog.h" | |
| 34 | 34 | |
| 35 | 35 | /* |
| 36 | 36 | * ocfs2 node maps are array of long int, which limits to send them freely |
| @@ -25,9 +25,9 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/delay.h> |
| 26 | 26 | |
| 27 | 27 | |
| 28 | −#include "cluster/heartbeat.h" | |
| 29 | −#include "cluster/nodemanager.h" | |
| 30 | −#include "cluster/tcp.h" | |
| 28 | +#include "../cluster/heartbeat.h" | |
| 29 | +#include "../cluster/nodemanager.h" | |
| 30 | +#include "../cluster/tcp.h" | |
| 31 | 31 | |
| 32 | 32 | #include "dlmapi.h" |
| 33 | 33 | #include "dlmcommon.h" |
| @@ -35,7 +35,7 @@ · 1 unmodified line | ||
| 35 | 35 | #include "dlmconvert.h" |
| 36 | 36 | |
| 37 | 37 | #define MLOG_MASK_PREFIX ML_DLM |
| 38 | −#include "cluster/masklog.h" | |
| 38 | +#include "../cluster/masklog.h" | |
| 39 | 39 | |
| 40 | 40 | static struct kmem_cache *dlm_lock_cache; |
| 41 | 41 | |
| @@ -25,9 +25,9 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/delay.h> |
| 26 | 26 | |
| 27 | 27 | |
| 28 | −#include "cluster/heartbeat.h" | |
| 29 | −#include "cluster/nodemanager.h" | |
| 30 | −#include "cluster/tcp.h" | |
| 28 | +#include "../cluster/heartbeat.h" | |
| 29 | +#include "../cluster/nodemanager.h" | |
| 30 | +#include "../cluster/tcp.h" | |
| 31 | 31 | |
| 32 | 32 | #include "dlmapi.h" |
| 33 | 33 | #include "dlmcommon.h" |
| @@ -35,7 +35,7 @@ · 1 unmodified line | ||
| 35 | 35 | #include "dlmdebug.h" |
| 36 | 36 | |
| 37 | 37 | #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_MASTER) |
| 38 | −#include "cluster/masklog.h" | |
| 38 | +#include "../cluster/masklog.h" | |
| 39 | 39 | |
| 40 | 40 | static void dlm_mle_node_down(struct dlm_ctxt *dlm, |
| 41 | 41 | struct dlm_master_list_entry *mle, |
| @@ -2554,8 +2554,6 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, · 2512 unmodified lines | ||
| 2554 | 2554 | if (!dlm_grab(dlm)) |
| 2555 | 2555 | return -EINVAL; |
| 2556 | 2556 | |
| 2557 | − BUG_ON(target == O2NM_MAX_NODES); | |
| 2558 | − | |
| 2559 | 2557 | name = res->lockname.name; |
| 2560 | 2558 | namelen = res->lockname.len; |
| 2561 | 2559 | |
| @@ -26,16 +26,16 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/delay.h> |
| 27 | 27 | |
| 28 | 28 | |
| 29 | −#include "cluster/heartbeat.h" | |
| 30 | −#include "cluster/nodemanager.h" | |
| 31 | −#include "cluster/tcp.h" | |
| 29 | +#include "../cluster/heartbeat.h" | |
| 30 | +#include "../cluster/nodemanager.h" | |
| 31 | +#include "../cluster/tcp.h" | |
| 32 | 32 | |
| 33 | 33 | #include "dlmapi.h" |
| 34 | 34 | #include "dlmcommon.h" |
| 35 | 35 | #include "dlmdomain.h" |
| 36 | 36 | |
| 37 | 37 | #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_RECOVERY) |
| 38 | −#include "cluster/masklog.h" | |
| 38 | +#include "../cluster/masklog.h" | |
| 39 | 39 | |
| 40 | 40 | static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node); |
| 41 | 41 | |
| @@ -1668,7 +1668,7 @@ static int dlm_lockres_master_requery(struct dlm_ctxt *dlm, · 1626 unmodified lines | ||
| 1668 | 1668 | int dlm_do_master_requery(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, |
| 1669 | 1669 | u8 nodenum, u8 *real_master) |
| 1670 | 1670 | { |
| 1671 | − int ret = -EINVAL; | |
| 1671 | + int ret; | |
| 1672 | 1672 | struct dlm_master_requery req; |
| 1673 | 1673 | int status = DLM_LOCK_RES_OWNER_UNKNOWN; |
| 1674 | 1674 | |
| @@ -25,16 +25,16 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/delay.h> |
| 26 | 26 | |
| 27 | 27 | |
| 28 | −#include "cluster/heartbeat.h" | |
| 29 | −#include "cluster/nodemanager.h" | |
| 30 | −#include "cluster/tcp.h" | |
| 28 | +#include "../cluster/heartbeat.h" | |
| 29 | +#include "../cluster/nodemanager.h" | |
| 30 | +#include "../cluster/tcp.h" | |
| 31 | 31 | |
| 32 | 32 | #include "dlmapi.h" |
| 33 | 33 | #include "dlmcommon.h" |
| 34 | 34 | #include "dlmdomain.h" |
| 35 | 35 | |
| 36 | 36 | #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_THREAD) |
| 37 | −#include "cluster/masklog.h" | |
| 37 | +#include "../cluster/masklog.h" | |
| 38 | 38 | |
| 39 | 39 | static int dlm_thread(void *data); |
| 40 | 40 | static void dlm_flush_asts(struct dlm_ctxt *dlm); |
| @@ -23,15 +23,15 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/spinlock.h> |
| 24 | 24 | #include <linux/delay.h> |
| 25 | 25 | |
| 26 | −#include "cluster/heartbeat.h" | |
| 27 | −#include "cluster/nodemanager.h" | |
| 28 | −#include "cluster/tcp.h" | |
| 26 | +#include "../cluster/heartbeat.h" | |
| 27 | +#include "../cluster/nodemanager.h" | |
| 28 | +#include "../cluster/tcp.h" | |
| 29 | 29 | |
| 30 | 30 | #include "dlmapi.h" |
| 31 | 31 | #include "dlmcommon.h" |
| 32 | 32 | |
| 33 | 33 | #define MLOG_MASK_PREFIX ML_DLM |
| 34 | −#include "cluster/masklog.h" | |
| 34 | +#include "../cluster/masklog.h" | |
| 35 | 35 | |
| 36 | 36 | #define DLM_UNLOCK_FREE_LOCK 0x00000001 |
| 37 | 37 | #define DLM_UNLOCK_CALL_AST 0x00000002 |
| @@ -1,6 +1,4 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | −ccflags-y := -I $(srctree)/$(src)/.. | |
| 3 | − | |
| 4 | 2 | obj-$(CONFIG_OCFS2_FS) += ocfs2_dlmfs.o |
| 5 | 3 | |
| 6 | 4 | ocfs2_dlmfs-objs := userdlm.o dlmfs.o |
| @@ -33,11 +33,11 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #include <linux/uaccess.h> |
| 35 | 35 | |
| 36 | −#include "stackglue.h" | |
| 36 | +#include "../stackglue.h" | |
| 37 | 37 | #include "userdlm.h" |
| 38 | 38 | |
| 39 | 39 | #define MLOG_MASK_PREFIX ML_DLMFS |
| 40 | −#include "cluster/masklog.h" | |
| 40 | +#include "../cluster/masklog.h" | |
| 41 | 41 | |
| 42 | 42 | |
| 43 | 43 | static const struct super_operations dlmfs_ops; |
| @@ -21,12 +21,12 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/types.h> |
| 22 | 22 | #include <linux/crc32.h> |
| 23 | 23 | |
| 24 | −#include "ocfs2_lockingver.h" | |
| 25 | −#include "stackglue.h" | |
| 24 | +#include "../ocfs2_lockingver.h" | |
| 25 | +#include "../stackglue.h" | |
| 26 | 26 | #include "userdlm.h" |
| 27 | 27 | |
| 28 | 28 | #define MLOG_MASK_PREFIX ML_DLMFS |
| 29 | −#include "cluster/masklog.h" | |
| 29 | +#include "../cluster/masklog.h" | |
| 30 | 30 | |
| 31 | 31 | |
| 32 | 32 | static inline struct user_lock_res *user_lksb_to_lock_res(struct ocfs2_dlm_lksb *lksb) |
| @@ -570,7 +570,7 @@ void ocfs2_inode_lock_res_init(struct ocfs2_lock_res *res, · 569 unmodified lines | ||
| 570 | 570 | mlog_bug_on_msg(1, "type: %d\n", type); |
| 571 | 571 | ops = NULL; /* thanks, gcc */ |
| 572 | 572 | break; |
| 573 | − }; | |
| 573 | + } | |
| 574 | 574 | |
| 575 | 575 | ocfs2_build_lock_name(type, OCFS2_I(inode)->ip_blkno, |
| 576 | 576 | generation, res->l_name); |
| @@ -597,9 +597,11 @@ static inline void ocfs2_update_inode_fsync_trans(handle_t *handle, · 596 unmodified lines | ||
| 597 | 597 | { |
| 598 | 598 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
| 599 | 599 | |
| 600 | − oi->i_sync_tid = handle->h_transaction->t_tid; | |
| 601 | − if (datasync) | |
| 602 | − oi->i_datasync_tid = handle->h_transaction->t_tid; | |
| 600 | + if (!is_handle_aborted(handle)) { | |
| 601 | + oi->i_sync_tid = handle->h_transaction->t_tid; | |
| 602 | + if (datasync) | |
| 603 | + oi->i_datasync_tid = handle->h_transaction->t_tid; | |
| 604 | + } | |
| 603 | 605 | } |
| 604 | 606 | |
| 605 | 607 | #endif /* OCFS2_JOURNAL_H */ |
| @@ -586,8 +586,7 @@ static int __ocfs2_mknod_locked(struct inode *dir, · 585 unmodified lines | ||
| 586 | 586 | mlog_errno(status); |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | − oi->i_sync_tid = handle->h_transaction->t_tid; | |
| 590 | − oi->i_datasync_tid = handle->h_transaction->t_tid; | |
| 589 | + ocfs2_update_inode_fsync_trans(handle, inode, 1); | |
| 591 | 590 | |
| 592 | 591 | leave: |
| 593 | 592 | if (status < 0) { |
| @@ -2240,7 +2240,8 @@ error_out: · 2239 unmodified lines | ||
| 2240 | 2240 | /* also releases the path */ |
| 2241 | 2241 | unfix_nodes(&s_ins_balance); |
| 2242 | 2242 | #ifdef REISERQUOTA_DEBUG |
| 2243 | − reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE, | |
| 2243 | + if (inode) | |
| 2244 | + reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE, | |
| 2244 | 2245 | "reiserquota insert_item(): freeing %u id=%u type=%c", |
| 2245 | 2246 | quota_bytes, inode->i_uid, head2type(ih)); |
| 2246 | 2247 | #endif |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/fs.h> |
| 14 | 14 | #include <linux/sched.h> |
| 15 | 15 | #include <linux/blkdev.h> |
| 16 | +#include <linux/device.h> | |
| 16 | 17 | #include <linux/writeback.h> |
| 17 | 18 | #include <linux/blk-cgroup.h> |
| 18 | 19 | #include <linux/backing-dev-defs.h> |
| @@ -504,4 +505,13 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi) · 485 unmodified lines | ||
| 504 | 505 | (1 << WB_async_congested)); |
| 505 | 506 | } |
| 506 | 507 | |
| 508 | +extern const char *bdi_unknown_name; | |
| 509 | + | |
| 510 | +static inline const char *bdi_dev_name(struct backing_dev_info *bdi) | |
| 511 | +{ | |
| 512 | + if (!bdi || !bdi->dev) | |
| 513 | + return bdi_unknown_name; | |
| 514 | + return dev_name(bdi->dev); | |
| 515 | +} | |
| 516 | + | |
| 507 | 517 | #endif /* _LINUX_BACKING_DEV_H */ |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE) |
| 15 | 15 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long)) |
| 16 | +#define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(char)) | |
| 16 | 17 | |
| 17 | 18 | extern unsigned int __sw_hweight8(unsigned int w); |
| 18 | 19 | extern unsigned int __sw_hweight16(unsigned int w); |
| @@ -2737,7 +2737,6 @@ static inline int filemap_fdatawait(struct address_space *mapping) · 2736 unmodified lines | ||
| 2737 | 2737 | |
| 2738 | 2738 | extern bool filemap_range_has_page(struct address_space *, loff_t lstart, |
| 2739 | 2739 | loff_t lend); |
| 2740 | −extern int filemap_write_and_wait(struct address_space *mapping); | |
| 2741 | 2740 | extern int filemap_write_and_wait_range(struct address_space *mapping, |
| 2742 | 2741 | loff_t lstart, loff_t lend); |
| 2743 | 2742 | extern int __filemap_fdatawrite_range(struct address_space *mapping, |
| @@ -2747,6 +2746,11 @@ extern int filemap_fdatawrite_range(struct address_space *mapping, · 3 unmodified lines | ||
| 2747 | 2746 | extern int filemap_check_errors(struct address_space *mapping); |
| 2748 | 2747 | extern void __filemap_set_wb_err(struct address_space *mapping, int err); |
| 2749 | 2748 | |
| 2749 | +static inline int filemap_write_and_wait(struct address_space *mapping) | |
| 2750 | +{ | |
| 2751 | + return filemap_write_and_wait_range(mapping, 0, LLONG_MAX); | |
| 2752 | +} | |
| 2753 | + | |
| 2750 | 2754 | extern int __must_check file_fdatawait_range(struct file *file, loff_t lstart, |
| 2751 | 2755 | loff_t lend); |
| 2752 | 2756 | extern int __must_check file_check_and_advance_wb_err(struct file *file); |
| @@ -28,6 +28,7 @@ struct io_mapping { · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #ifdef CONFIG_HAVE_ATOMIC_IOMAP |
| 30 | 30 | |
| 31 | +#include <linux/pfn.h> | |
| 31 | 32 | #include <asm/iomap.h> |
| 32 | 33 | /* |
| 33 | 34 | * For small address space machines, mapping large objects |
| @@ -64,12 +65,10 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping, · 30 unmodified lines | ||
| 64 | 65 | unsigned long offset) |
| 65 | 66 | { |
| 66 | 67 | resource_size_t phys_addr; |
| 67 | − unsigned long pfn; | |
| 68 | 68 | |
| 69 | 69 | BUG_ON(offset >= mapping->size); |
| 70 | 70 | phys_addr = mapping->base + offset; |
| 71 | − pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); | |
| 72 | − return iomap_atomic_prot_pfn(pfn, mapping->prot); | |
| 71 | + return iomap_atomic_prot_pfn(PHYS_PFN(phys_addr), mapping->prot); | |
| 73 | 72 | } |
| 74 | 73 | |
| 75 | 74 | static inline void |
| @@ -113,6 +113,9 @@ int memblock_add(phys_addr_t base, phys_addr_t size); · 112 unmodified lines | ||
| 113 | 113 | int memblock_remove(phys_addr_t base, phys_addr_t size); |
| 114 | 114 | int memblock_free(phys_addr_t base, phys_addr_t size); |
| 115 | 115 | int memblock_reserve(phys_addr_t base, phys_addr_t size); |
| 116 | +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP | |
| 117 | +int memblock_physmem_add(phys_addr_t base, phys_addr_t size); | |
| 118 | +#endif | |
| 116 | 119 | void memblock_trim_memory(phys_addr_t align); |
| 117 | 120 | bool memblock_overlaps_region(struct memblock_type *type, |
| 118 | 121 | phys_addr_t base, phys_addr_t size); |
| @@ -127,10 +130,6 @@ void reset_node_managed_pages(pg_data_t *pgdat); · 8 unmodified lines | ||
| 127 | 130 | void reset_all_zones_managed_pages(void); |
| 128 | 131 | |
| 129 | 132 | /* Low level functions */ |
| 130 | −int memblock_add_range(struct memblock_type *type, | |
| 131 | − phys_addr_t base, phys_addr_t size, | |
| 132 | − int nid, enum memblock_flags flags); | |
| 133 | − | |
| 134 | 133 | void __next_mem_range(u64 *idx, int nid, enum memblock_flags flags, |
| 135 | 134 | struct memblock_type *type_a, |
| 136 | 135 | struct memblock_type *type_b, phys_addr_t *out_start, |
| @@ -29,8 +29,6 @@ struct memory_block { · 28 unmodified lines | ||
| 29 | 29 | int section_count; /* serialized by mem_sysfs_mutex */ |
| 30 | 30 | int online_type; /* for passing data to online routine */ |
| 31 | 31 | int phys_device; /* to which fru does this belong? */ |
| 32 | − void *hw; /* optional pointer to fw/hw data */ | |
| 33 | − int (*phys_callback)(struct memory_block *); | |
| 34 | 32 | struct device dev; |
| 35 | 33 | int nid; /* NID for this memory block */ |
| 36 | 34 | }; |
| @@ -55,19 +53,6 @@ struct memory_notify { · 18 unmodified lines | ||
| 55 | 53 | int status_change_nid; |
| 56 | 54 | }; |
| 57 | 55 | |
| 58 | −/* | |
| 59 | − * During pageblock isolation, count the number of pages within the | |
| 60 | − * range [start_pfn, start_pfn + nr_pages) which are owned by code | |
| 61 | − * in the notifier chain. | |
| 62 | − */ | |
| 63 | −#define MEM_ISOLATE_COUNT (1<<0) | |
| 64 | − | |
| 65 | −struct memory_isolate_notify { | |
| 66 | − unsigned long start_pfn; /* Start of range to check */ | |
| 67 | − unsigned int nr_pages; /* # pages in range to check */ | |
| 68 | − unsigned int pages_found; /* # pages owned found by callbacks */ | |
| 69 | −}; | |
| 70 | − | |
| 71 | 56 | struct notifier_block; |
| 72 | 57 | struct mem_section; |
| 73 | 58 | |
| @@ -94,27 +79,13 @@ static inline int memory_notify(unsigned long val, void *v) · 20 unmodified lines | ||
| 94 | 79 | { |
| 95 | 80 | return 0; |
| 96 | 81 | } |
| 97 | −static inline int register_memory_isolate_notifier(struct notifier_block *nb) | |
| 98 | −{ | |
| 99 | − return 0; | |
| 100 | −} | |
| 101 | −static inline void unregister_memory_isolate_notifier(struct notifier_block *nb) | |
| 102 | −{ | |
| 103 | −} | |
| 104 | −static inline int memory_isolate_notify(unsigned long val, void *v) | |
| 105 | −{ | |
| 106 | − return 0; | |
| 107 | −} | |
| 108 | 82 | #else |
| 109 | 83 | extern int register_memory_notifier(struct notifier_block *nb); |
| 110 | 84 | extern void unregister_memory_notifier(struct notifier_block *nb); |
| 111 | −extern int register_memory_isolate_notifier(struct notifier_block *nb); | |
| 112 | −extern void unregister_memory_isolate_notifier(struct notifier_block *nb); | |
| 113 | 85 | int create_memory_block_devices(unsigned long start, unsigned long size); |
| 114 | 86 | void remove_memory_block_devices(unsigned long start, unsigned long size); |
| 115 | 87 | extern void memory_dev_init(void); |
| 116 | 88 | extern int memory_notify(unsigned long val, void *v); |
| 117 | −extern int memory_isolate_notify(unsigned long val, void *v); | |
| 118 | 89 | extern struct memory_block *find_memory_block(struct mem_section *); |
| 119 | 90 | typedef int (*walk_memory_blocks_func_t)(struct memory_block *, void *); |
| 120 | 91 | extern int walk_memory_blocks(unsigned long start, unsigned long size, |
| @@ -94,7 +94,8 @@ extern int zone_grow_free_lists(struct zone *zone, unsigned long new_nr_pages); · 93 unmodified lines | ||
| 94 | 94 | extern int zone_grow_waitqueues(struct zone *zone, unsigned long nr_pages); |
| 95 | 95 | extern int add_one_highpage(struct page *page, int pfn, int bad_ppro); |
| 96 | 96 | /* VM interface that may be used by firmware interface */ |
| 97 | −extern int online_pages(unsigned long, unsigned long, int); | |
| 97 | +extern int online_pages(unsigned long pfn, unsigned long nr_pages, | |
| 98 | + int online_type, int nid); | |
| 98 | 99 | extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, |
| 99 | 100 | unsigned long *valid_start, unsigned long *valid_end); |
| 100 | 101 | extern unsigned long __offline_isolated_pages(unsigned long start_pfn, |
| @@ -70,11 +70,6 @@ static inline void totalram_pages_add(long count) · 69 unmodified lines | ||
| 70 | 70 | atomic_long_add(count, &_totalram_pages); |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | −static inline void totalram_pages_set(long val) | |
| 74 | −{ | |
| 75 | − atomic_long_set(&_totalram_pages, val); | |
| 76 | −} | |
| 77 | − | |
| 78 | 73 | extern void * high_memory; |
| 79 | 74 | extern int page_cluster; |
| 80 | 75 | |
| @@ -916,10 +911,6 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf); · 835 unmodified lines | ||
| 916 | 911 | |
| 917 | 912 | #define ZONEID_PGSHIFT (ZONEID_PGOFF * (ZONEID_SHIFT != 0)) |
| 918 | 913 | |
| 919 | −#if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > BITS_PER_LONG - NR_PAGEFLAGS | |
| 920 | −#error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > BITS_PER_LONG - NR_PAGEFLAGS | |
| 921 | −#endif | |
| 922 | − | |
| 923 | 914 | #define ZONES_MASK ((1UL << ZONES_WIDTH) - 1) |
| 924 | 915 | #define NODES_MASK ((1UL << NODES_WIDTH) - 1) |
| 925 | 916 | #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) |
| @@ -947,9 +938,10 @@ static inline bool is_zone_device_page(const struct page *page) · 21 unmodified lines | ||
| 947 | 938 | #endif |
| 948 | 939 | |
| 949 | 940 | #ifdef CONFIG_DEV_PAGEMAP_OPS |
| 950 | −void __put_devmap_managed_page(struct page *page); | |
| 941 | +void free_devmap_managed_page(struct page *page); | |
| 951 | 942 | DECLARE_STATIC_KEY_FALSE(devmap_managed_key); |
| 952 | −static inline bool put_devmap_managed_page(struct page *page) | |
| 943 | + | |
| 944 | +static inline bool page_is_devmap_managed(struct page *page) | |
| 953 | 945 | { |
| 954 | 946 | if (!static_branch_unlikely(&devmap_managed_key)) |
| 955 | 947 | return false; |
| @@ -958,7 +950,6 @@ static inline bool put_devmap_managed_page(struct page *page) · 2 unmodified lines | ||
| 958 | 950 | switch (page->pgmap->type) { |
| 959 | 951 | case MEMORY_DEVICE_PRIVATE: |
| 960 | 952 | case MEMORY_DEVICE_FS_DAX: |
| 961 | − __put_devmap_managed_page(page); | |
| 962 | 953 | return true; |
| 963 | 954 | default: |
| 964 | 955 | break; |
| @@ -966,11 +957,17 @@ static inline bool put_devmap_managed_page(struct page *page) · 1 unmodified line | ||
| 966 | 957 | return false; |
| 967 | 958 | } |
| 968 | 959 | |
| 960 | +void put_devmap_managed_page(struct page *page); | |
| 961 | + | |
| 969 | 962 | #else /* CONFIG_DEV_PAGEMAP_OPS */ |
| 970 | −static inline bool put_devmap_managed_page(struct page *page) | |
| 963 | +static inline bool page_is_devmap_managed(struct page *page) | |
| 971 | 964 | { |
| 972 | 965 | return false; |
| 973 | 966 | } |
| 967 | + | |
| 968 | +static inline void put_devmap_managed_page(struct page *page) | |
| 969 | +{ | |
| 970 | +} | |
| 974 | 971 | #endif /* CONFIG_DEV_PAGEMAP_OPS */ |
| 975 | 972 | |
| 976 | 973 | static inline bool is_device_private_page(const struct page *page) |
| @@ -1023,37 +1020,37 @@ static inline void put_page(struct page *page) · 46 unmodified lines | ||
| 1023 | 1020 | * need to inform the device driver through callback. See |
| 1024 | 1021 | * include/linux/memremap.h and HMM for details. |
| 1025 | 1022 | */ |
| 1026 | − if (put_devmap_managed_page(page)) | |
| 1023 | + if (page_is_devmap_managed(page)) { | |
| 1024 | + put_devmap_managed_page(page); | |
| 1027 | 1025 | return; |
| 1026 | + } | |
| 1028 | 1027 | |
| 1029 | 1028 | if (put_page_testzero(page)) |
| 1030 | 1029 | __put_page(page); |
| 1031 | 1030 | } |
| 1032 | 1031 | |
| 1033 | 1032 | /** |
| 1034 | − * put_user_page() - release a gup-pinned page | |
| 1033 | + * unpin_user_page() - release a gup-pinned page | |
| 1035 | 1034 | * @page: pointer to page to be released |
| 1036 | 1035 | * |
| 1037 | − * Pages that were pinned via get_user_pages*() must be released via | |
| 1038 | − * either put_user_page(), or one of the put_user_pages*() routines | |
| 1039 | − * below. This is so that eventually, pages that are pinned via | |
| 1040 | − * get_user_pages*() can be separately tracked and uniquely handled. In | |
| 1041 | − * particular, interactions with RDMA and filesystems need special | |
| 1042 | − * handling. | |
| 1036 | + * Pages that were pinned via pin_user_pages*() must be released via either | |
| 1037 | + * unpin_user_page(), or one of the unpin_user_pages*() routines. This is so | |
| 1038 | + * that eventually such pages can be separately tracked and uniquely handled. In | |
| 1039 | + * particular, interactions with RDMA and filesystems need special handling. | |
| 1043 | 1040 | * |
| 1044 | − * put_user_page() and put_page() are not interchangeable, despite this early | |
| 1045 | − * implementation that makes them look the same. put_user_page() calls must | |
| 1046 | − * be perfectly matched up with get_user_page() calls. | |
| 1041 | + * unpin_user_page() and put_page() are not interchangeable, despite this early | |
| 1042 | + * implementation that makes them look the same. unpin_user_page() calls must | |
| 1043 | + * be perfectly matched up with pin*() calls. | |
| 1047 | 1044 | */ |
| 1048 | −static inline void put_user_page(struct page *page) | |
| 1045 | +static inline void unpin_user_page(struct page *page) | |
| 1049 | 1046 | { |
| 1050 | 1047 | put_page(page); |
| 1051 | 1048 | } |
| 1052 | 1049 | |
| 1053 | −void put_user_pages_dirty_lock(struct page **pages, unsigned long npages, | |
| 1054 | − bool make_dirty); | |
| 1050 | +void unpin_user_pages_dirty_lock(struct page **pages, unsigned long npages, | |
| 1051 | + bool make_dirty); | |
| 1055 | 1052 | |
| 1056 | −void put_user_pages(struct page **pages, unsigned long npages); | |
| 1053 | +void unpin_user_pages(struct page **pages, unsigned long npages); | |
| 1057 | 1054 | |
| 1058 | 1055 | #if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP) |
| 1059 | 1056 | #define SECTION_IN_PAGE_FLAGS |
| @@ -1501,9 +1498,16 @@ long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, · 441 unmodified lines | ||
| 1501 | 1498 | unsigned long start, unsigned long nr_pages, |
| 1502 | 1499 | unsigned int gup_flags, struct page **pages, |
| 1503 | 1500 | struct vm_area_struct **vmas, int *locked); |
| 1501 | +long pin_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, | |
| 1502 | + unsigned long start, unsigned long nr_pages, | |
| 1503 | + unsigned int gup_flags, struct page **pages, | |
| 1504 | + struct vm_area_struct **vmas, int *locked); | |
| 1504 | 1505 | long get_user_pages(unsigned long start, unsigned long nr_pages, |
| 1505 | 1506 | unsigned int gup_flags, struct page **pages, |
| 1506 | 1507 | struct vm_area_struct **vmas); |
| 1508 | +long pin_user_pages(unsigned long start, unsigned long nr_pages, | |
| 1509 | + unsigned int gup_flags, struct page **pages, | |
| 1510 | + struct vm_area_struct **vmas); | |
| 1507 | 1511 | long get_user_pages_locked(unsigned long start, unsigned long nr_pages, |
| 1508 | 1512 | unsigned int gup_flags, struct page **pages, int *locked); |
| 1509 | 1513 | long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, |
| @@ -1511,6 +1515,8 @@ long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, · 1 unmodified line | ||
| 1511 | 1515 | |
| 1512 | 1516 | int get_user_pages_fast(unsigned long start, int nr_pages, |
| 1513 | 1517 | unsigned int gup_flags, struct page **pages); |
| 1518 | +int pin_user_pages_fast(unsigned long start, int nr_pages, | |
| 1519 | + unsigned int gup_flags, struct page **pages); | |
| 1514 | 1520 | |
| 1515 | 1521 | int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc); |
| 1516 | 1522 | int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, |
| @@ -2575,13 +2581,15 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, · 1058 unmodified lines | ||
| 2575 | 2581 | #define FOLL_ANON 0x8000 /* don't do file mappings */ |
| 2576 | 2582 | #define FOLL_LONGTERM 0x10000 /* mapping lifetime is indefinite: see below */ |
| 2577 | 2583 | #define FOLL_SPLIT_PMD 0x20000 /* split huge pmd before returning */ |
| 2584 | +#define FOLL_PIN 0x40000 /* pages must be released via unpin_user_page */ | |
| 2578 | 2585 | |
| 2579 | 2586 | /* |
| 2580 | − * NOTE on FOLL_LONGTERM: | |
| 2587 | + * FOLL_PIN and FOLL_LONGTERM may be used in various combinations with each | |
| 2588 | + * other. Here is what they mean, and how to use them: | |
| 2581 | 2589 | * |
| 2582 | 2590 | * FOLL_LONGTERM indicates that the page will be held for an indefinite time |
| 2583 | − * period _often_ under userspace control. This is contrasted with | |
| 2584 | − * iov_iter_get_pages() where usages which are transient. | |
| 2591 | + * period _often_ under userspace control. This is in contrast to | |
| 2592 | + * iov_iter_get_pages(), whose usages are transient. | |
| 2585 | 2593 | * |
| 2586 | 2594 | * FIXME: For pages which are part of a filesystem, mappings are subject to the |
| 2587 | 2595 | * lifetime enforced by the filesystem and we need guarantees that longterm |
| @@ -2596,11 +2604,39 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, · 8 unmodified lines | ||
| 2596 | 2604 | * Currently only get_user_pages() and get_user_pages_fast() support this flag |
| 2597 | 2605 | * and calls to get_user_pages_[un]locked are specifically not allowed. This |
| 2598 | 2606 | * is due to an incompatibility with the FS DAX check and |
| 2599 | − * FAULT_FLAG_ALLOW_RETRY | |
| 2607 | + * FAULT_FLAG_ALLOW_RETRY. | |
| 2600 | 2608 | * |
| 2601 | − * In the CMA case: longterm pins in a CMA region would unnecessarily fragment | |
| 2602 | − * that region. And so CMA attempts to migrate the page before pinning when | |
| 2609 | + * In the CMA case: long term pins in a CMA region would unnecessarily fragment | |
| 2610 | + * that region. And so, CMA attempts to migrate the page before pinning, when | |
| 2603 | 2611 | * FOLL_LONGTERM is specified. |
| 2612 | + * | |
| 2613 | + * FOLL_PIN indicates that a special kind of tracking (not just page->_refcount, | |
| 2614 | + * but an additional pin counting system) will be invoked. This is intended for | |
| 2615 | + * anything that gets a page reference and then touches page data (for example, | |
| 2616 | + * Direct IO). This lets the filesystem know that some non-file-system entity is | |
| 2617 | + * potentially changing the pages' data. In contrast to FOLL_GET (whose pages | |
| 2618 | + * are released via put_page()), FOLL_PIN pages must be released, ultimately, by | |
| 2619 | + * a call to unpin_user_page(). | |
| 2620 | + * | |
| 2621 | + * FOLL_PIN is similar to FOLL_GET: both of these pin pages. They use different | |
| 2622 | + * and separate refcounting mechanisms, however, and that means that each has | |
| 2623 | + * its own acquire and release mechanisms: | |
| 2624 | + * | |
| 2625 | + * FOLL_GET: get_user_pages*() to acquire, and put_page() to release. | |
| 2626 | + * | |
| 2627 | + * FOLL_PIN: pin_user_pages*() to acquire, and unpin_user_pages to release. | |
| 2628 | + * | |
| 2629 | + * FOLL_PIN and FOLL_GET are mutually exclusive for a given function call. | |
| 2630 | + * (The underlying pages may experience both FOLL_GET-based and FOLL_PIN-based | |
| 2631 | + * calls applied to them, and that's perfectly OK. This is a constraint on the | |
| 2632 | + * callers, not on the pages.) | |
| 2633 | + * | |
| 2634 | + * FOLL_PIN should be set internally by the pin_user_pages*() APIs, never | |
| 2635 | + * directly by the caller. That's in order to help avoid mismatches when | |
| 2636 | + * releasing pages: get_user_pages*() pages must be released via put_page(), | |
| 2637 | + * while pin_user_pages*() pages must be released via unpin_user_page(). | |
| 2638 | + * | |
| 2639 | + * Please see Documentation/vm/pin_user_pages.rst for more information. | |
| 2604 | 2640 | */ |
| 2605 | 2641 | |
| 2606 | 2642 | static inline int vm_fault_to_errno(vm_fault_t vm_fault, int foll_flags) |
| @@ -758,7 +758,7 @@ typedef struct pglist_data { · 757 unmodified lines | ||
| 758 | 758 | |
| 759 | 759 | #ifdef CONFIG_NUMA |
| 760 | 760 | /* |
| 761 | − * zone reclaim becomes active if more unmapped pages exist. | |
| 761 | + * node reclaim becomes active if more unmapped pages exist. | |
| 762 | 762 | */ |
| 763 | 763 | unsigned long min_unmapped_pages; |
| 764 | 764 | unsigned long min_slab_pages; |
| @@ -33,8 +33,8 @@ static inline bool is_migrate_isolate(int migratetype) · 32 unmodified lines | ||
| 33 | 33 | #define MEMORY_OFFLINE 0x1 |
| 34 | 34 | #define REPORT_FAILURE 0x2 |
| 35 | 35 | |
| 36 | −bool has_unmovable_pages(struct zone *zone, struct page *page, int count, | |
| 37 | − int migratetype, int flags); | |
| 36 | +struct page *has_unmovable_pages(struct zone *zone, struct page *page, | |
| 37 | + int migratetype, int flags); | |
| 38 | 38 | void set_pageblock_migratetype(struct page *page, int migratetype); |
| 39 | 39 | int move_freepages_block(struct zone *zone, struct page *page, |
| 40 | 40 | int migratetype, int *num_movable); |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | # define swab16 __swab16 |
| 8 | 8 | # define swab32 __swab32 |
| 9 | 9 | # define swab64 __swab64 |
| 10 | +# define swab __swab | |
| 10 | 11 | # define swahw32 __swahw32 |
| 11 | 12 | # define swahb32 __swahb32 |
| 12 | 13 | # define swab16p __swab16p |
| @@ -32,17 +32,6 @@ · 31 unmodified lines | ||
| 32 | 32 | /* use value, which < 0K, to indicate an invalid/uninitialized temperature */ |
| 33 | 33 | #define THERMAL_TEMP_INVALID -274000 |
| 34 | 34 | |
| 35 | −/* Unit conversion macros */ | |
| 36 | −#define DECI_KELVIN_TO_CELSIUS(t) ({ \ | |
| 37 | − long _t = (t); \ | |
| 38 | − ((_t-2732 >= 0) ? (_t-2732+5)/10 : (_t-2732-5)/10); \ | |
| 39 | −}) | |
| 40 | −#define CELSIUS_TO_DECI_KELVIN(t) ((t)*10+2732) | |
| 41 | −#define DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET(t, off) (((t) - (off)) * 100) | |
| 42 | −#define DECI_KELVIN_TO_MILLICELSIUS(t) DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET(t, 2732) | |
| 43 | −#define MILLICELSIUS_TO_DECI_KELVIN_WITH_OFFSET(t, off) (((t) / 100) + (off)) | |
| 44 | −#define MILLICELSIUS_TO_DECI_KELVIN(t) MILLICELSIUS_TO_DECI_KELVIN_WITH_OFFSET(t, 2732) | |
| 45 | − | |
| 46 | 35 | /* Default Thermal Governor */ |
| 47 | 36 | #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE) |
| 48 | 37 | #define DEFAULT_THERMAL_GOVERNOR "step_wise" |
| @@ -0,0 +1,84 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +#ifndef _LINUX_UNITS_H | |
| 3 | +#define _LINUX_UNITS_H | |
| 4 | + | |
| 5 | +#include <linux/kernel.h> | |
| 6 | + | |
| 7 | +#define ABSOLUTE_ZERO_MILLICELSIUS -273150 | |
| 8 | + | |
| 9 | +static inline long milli_kelvin_to_millicelsius(long t) | |
| 10 | +{ | |
| 11 | + return t + ABSOLUTE_ZERO_MILLICELSIUS; | |
| 12 | +} | |
| 13 | + | |
| 14 | +static inline long millicelsius_to_milli_kelvin(long t) | |
| 15 | +{ | |
| 16 | + return t - ABSOLUTE_ZERO_MILLICELSIUS; | |
| 17 | +} | |
| 18 | + | |
| 19 | +#define MILLIDEGREE_PER_DEGREE 1000 | |
| 20 | +#define MILLIDEGREE_PER_DECIDEGREE 100 | |
| 21 | + | |
| 22 | +static inline long kelvin_to_millicelsius(long t) | |
| 23 | +{ | |
| 24 | + return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DEGREE); | |
| 25 | +} | |
| 26 | + | |
| 27 | +static inline long millicelsius_to_kelvin(long t) | |
| 28 | +{ | |
| 29 | + t = millicelsius_to_milli_kelvin(t); | |
| 30 | + | |
| 31 | + return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE); | |
| 32 | +} | |
| 33 | + | |
| 34 | +static inline long deci_kelvin_to_celsius(long t) | |
| 35 | +{ | |
| 36 | + t = milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE); | |
| 37 | + | |
| 38 | + return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE); | |
| 39 | +} | |
| 40 | + | |
| 41 | +static inline long celsius_to_deci_kelvin(long t) | |
| 42 | +{ | |
| 43 | + t = millicelsius_to_milli_kelvin(t * MILLIDEGREE_PER_DEGREE); | |
| 44 | + | |
| 45 | + return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE); | |
| 46 | +} | |
| 47 | + | |
| 48 | +/** | |
| 49 | + * deci_kelvin_to_millicelsius_with_offset - convert Kelvin to Celsius | |
| 50 | + * @t: temperature value in decidegrees Kelvin | |
| 51 | + * @offset: difference between Kelvin and Celsius in millidegrees | |
| 52 | + * | |
| 53 | + * Return: temperature value in millidegrees Celsius | |
| 54 | + */ | |
| 55 | +static inline long deci_kelvin_to_millicelsius_with_offset(long t, long offset) | |
| 56 | +{ | |
| 57 | + return t * MILLIDEGREE_PER_DECIDEGREE - offset; | |
| 58 | +} | |
| 59 | + | |
| 60 | +static inline long deci_kelvin_to_millicelsius(long t) | |
| 61 | +{ | |
| 62 | + return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE); | |
| 63 | +} | |
| 64 | + | |
| 65 | +static inline long millicelsius_to_deci_kelvin(long t) | |
| 66 | +{ | |
| 67 | + t = millicelsius_to_milli_kelvin(t); | |
| 68 | + | |
| 69 | + return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE); | |
| 70 | +} | |
| 71 | + | |
| 72 | +static inline long kelvin_to_celsius(long t) | |
| 73 | +{ | |
| 74 | + return t + DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS, | |
| 75 | + MILLIDEGREE_PER_DEGREE); | |
| 76 | +} | |
| 77 | + | |
| 78 | +static inline long celsius_to_kelvin(long t) | |
| 79 | +{ | |
| 80 | + return t - DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS, | |
| 81 | + MILLIDEGREE_PER_DEGREE); | |
| 82 | +} | |
| 83 | + | |
| 84 | +#endif /* _LINUX_UNITS_H */ | |
| @@ -191,6 +191,12 @@ extern int zlib_deflate_workspacesize (int windowBits, int memLevel); · 190 unmodified lines | ||
| 191 | 191 | exceed those passed here. |
| 192 | 192 | */ |
| 193 | 193 | |
| 194 | +extern int zlib_deflate_dfltcc_enabled (void); | |
| 195 | +/* | |
| 196 | + Returns 1 if Deflate-Conversion facility is installed and enabled, | |
| 197 | + otherwise 0. | |
| 198 | +*/ | |
| 199 | + | |
| 194 | 200 | /* |
| 195 | 201 | extern int deflateInit (z_streamp strm, int level); |
| 196 | 202 | |
| @@ -88,8 +88,8 @@ DECLARE_EVENT_CLASS(kmem_alloc_node, · 87 unmodified lines | ||
| 88 | 88 | __entry->node = node; |
| 89 | 89 | ), |
| 90 | 90 | |
| 91 | − TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", | |
| 92 | − __entry->call_site, | |
| 91 | + TP_printk("call_site=%pS ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", | |
| 92 | + (void *)__entry->call_site, | |
| 93 | 93 | __entry->ptr, |
| 94 | 94 | __entry->bytes_req, |
| 95 | 95 | __entry->bytes_alloc, |
| @@ -67,8 +67,8 @@ DECLARE_EVENT_CLASS(writeback_page_template, · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | TP_fast_assign( |
| 69 | 69 | strscpy_pad(__entry->name, |
| 70 | − mapping ? dev_name(inode_to_bdi(mapping->host)->dev) : "(unknown)", | |
| 71 | − 32); | |
| 70 | + bdi_dev_name(mapping ? inode_to_bdi(mapping->host) : | |
| 71 | + NULL), 32); | |
| 72 | 72 | __entry->ino = mapping ? mapping->host->i_ino : 0; |
| 73 | 73 | __entry->index = page->index; |
| 74 | 74 | ), |
| @@ -111,8 +111,7 @@ DECLARE_EVENT_CLASS(writeback_dirty_inode_template, · 36 unmodified lines | ||
| 111 | 111 | struct backing_dev_info *bdi = inode_to_bdi(inode); |
| 112 | 112 | |
| 113 | 113 | /* may be called for files on pseudo FSes w/ unregistered bdi */ |
| 114 | − strscpy_pad(__entry->name, | |
| 115 | − bdi->dev ? dev_name(bdi->dev) : "(unknown)", 32); | |
| 114 | + strscpy_pad(__entry->name, bdi_dev_name(bdi), 32); | |
| 116 | 115 | __entry->ino = inode->i_ino; |
| 117 | 116 | __entry->state = inode->i_state; |
| 118 | 117 | __entry->flags = flags; |
| @@ -193,7 +192,7 @@ TRACE_EVENT(inode_foreign_history, · 74 unmodified lines | ||
| 193 | 192 | ), |
| 194 | 193 | |
| 195 | 194 | TP_fast_assign( |
| 196 | − strncpy(__entry->name, dev_name(inode_to_bdi(inode)->dev), 32); | |
| 195 | + strncpy(__entry->name, bdi_dev_name(inode_to_bdi(inode)), 32); | |
| 197 | 196 | __entry->ino = inode->i_ino; |
| 198 | 197 | __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc); |
| 199 | 198 | __entry->history = history; |
| @@ -222,7 +221,7 @@ TRACE_EVENT(inode_switch_wbs, · 22 unmodified lines | ||
| 222 | 221 | ), |
| 223 | 222 | |
| 224 | 223 | TP_fast_assign( |
| 225 | − strncpy(__entry->name, dev_name(old_wb->bdi->dev), 32); | |
| 224 | + strncpy(__entry->name, bdi_dev_name(old_wb->bdi), 32); | |
| 226 | 225 | __entry->ino = inode->i_ino; |
| 227 | 226 | __entry->old_cgroup_ino = __trace_wb_assign_cgroup(old_wb); |
| 228 | 227 | __entry->new_cgroup_ino = __trace_wb_assign_cgroup(new_wb); |
| @@ -255,7 +254,7 @@ TRACE_EVENT(track_foreign_dirty, · 26 unmodified lines | ||
| 255 | 254 | struct address_space *mapping = page_mapping(page); |
| 256 | 255 | struct inode *inode = mapping ? mapping->host : NULL; |
| 257 | 256 | |
| 258 | − strncpy(__entry->name, dev_name(wb->bdi->dev), 32); | |
| 257 | + strncpy(__entry->name, bdi_dev_name(wb->bdi), 32); | |
| 259 | 258 | __entry->bdi_id = wb->bdi->id; |
| 260 | 259 | __entry->ino = inode ? inode->i_ino : 0; |
| 261 | 260 | __entry->memcg_id = wb->memcg_css->id; |
| @@ -288,7 +287,7 @@ TRACE_EVENT(flush_foreign, · 26 unmodified lines | ||
| 288 | 287 | ), |
| 289 | 288 | |
| 290 | 289 | TP_fast_assign( |
| 291 | − strncpy(__entry->name, dev_name(wb->bdi->dev), 32); | |
| 290 | + strncpy(__entry->name, bdi_dev_name(wb->bdi), 32); | |
| 292 | 291 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb); |
| 293 | 292 | __entry->frn_bdi_id = frn_bdi_id; |
| 294 | 293 | __entry->frn_memcg_id = frn_memcg_id; |
| @@ -318,7 +317,7 @@ DECLARE_EVENT_CLASS(writeback_write_inode_template, · 23 unmodified lines | ||
| 318 | 317 | |
| 319 | 318 | TP_fast_assign( |
| 320 | 319 | strscpy_pad(__entry->name, |
| 321 | − dev_name(inode_to_bdi(inode)->dev), 32); | |
| 320 | + bdi_dev_name(inode_to_bdi(inode)), 32); | |
| 322 | 321 | __entry->ino = inode->i_ino; |
| 323 | 322 | __entry->sync_mode = wbc->sync_mode; |
| 324 | 323 | __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc); |
| @@ -361,9 +360,7 @@ DECLARE_EVENT_CLASS(writeback_work_class, · 36 unmodified lines | ||
| 361 | 360 | __field(ino_t, cgroup_ino) |
| 362 | 361 | ), |
| 363 | 362 | TP_fast_assign( |
| 364 | − strscpy_pad(__entry->name, | |
| 365 | − wb->bdi->dev ? dev_name(wb->bdi->dev) : | |
| 366 | − "(unknown)", 32); | |
| 363 | + strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32); | |
| 367 | 364 | __entry->nr_pages = work->nr_pages; |
| 368 | 365 | __entry->sb_dev = work->sb ? work->sb->s_dev : 0; |
| 369 | 366 | __entry->sync_mode = work->sync_mode; |
| @@ -416,7 +413,7 @@ DECLARE_EVENT_CLASS(writeback_class, · 46 unmodified lines | ||
| 416 | 413 | __field(ino_t, cgroup_ino) |
| 417 | 414 | ), |
| 418 | 415 | TP_fast_assign( |
| 419 | − strscpy_pad(__entry->name, dev_name(wb->bdi->dev), 32); | |
| 416 | + strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32); | |
| 420 | 417 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb); |
| 421 | 418 | ), |
| 422 | 419 | TP_printk("bdi %s: cgroup_ino=%lu", |
| @@ -438,7 +435,7 @@ TRACE_EVENT(writeback_bdi_register, · 15 unmodified lines | ||
| 438 | 435 | __array(char, name, 32) |
| 439 | 436 | ), |
| 440 | 437 | TP_fast_assign( |
| 441 | − strscpy_pad(__entry->name, dev_name(bdi->dev), 32); | |
| 438 | + strscpy_pad(__entry->name, bdi_dev_name(bdi), 32); | |
| 442 | 439 | ), |
| 443 | 440 | TP_printk("bdi %s", |
| 444 | 441 | __entry->name |
| @@ -463,7 +460,7 @@ DECLARE_EVENT_CLASS(wbc_class, · 18 unmodified lines | ||
| 463 | 460 | ), |
| 464 | 461 | |
| 465 | 462 | TP_fast_assign( |
| 466 | − strscpy_pad(__entry->name, dev_name(bdi->dev), 32); | |
| 463 | + strscpy_pad(__entry->name, bdi_dev_name(bdi), 32); | |
| 467 | 464 | __entry->nr_to_write = wbc->nr_to_write; |
| 468 | 465 | __entry->pages_skipped = wbc->pages_skipped; |
| 469 | 466 | __entry->sync_mode = wbc->sync_mode; |
| @@ -514,7 +511,7 @@ TRACE_EVENT(writeback_queue_io, · 44 unmodified lines | ||
| 514 | 511 | ), |
| 515 | 512 | TP_fast_assign( |
| 516 | 513 | unsigned long *older_than_this = work->older_than_this; |
| 517 | − strscpy_pad(__entry->name, dev_name(wb->bdi->dev), 32); | |
| 514 | + strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32); | |
| 518 | 515 | __entry->older = older_than_this ? *older_than_this : 0; |
| 519 | 516 | __entry->age = older_than_this ? |
| 520 | 517 | (jiffies - *older_than_this) * 1000 / HZ : -1; |
| @@ -600,7 +597,7 @@ TRACE_EVENT(bdi_dirty_ratelimit, · 79 unmodified lines | ||
| 600 | 597 | ), |
| 601 | 598 | |
| 602 | 599 | TP_fast_assign( |
| 603 | − strscpy_pad(__entry->bdi, dev_name(wb->bdi->dev), 32); | |
| 600 | + strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32); | |
| 604 | 601 | __entry->write_bw = KBps(wb->write_bandwidth); |
| 605 | 602 | __entry->avg_write_bw = KBps(wb->avg_write_bandwidth); |
| 606 | 603 | __entry->dirty_rate = KBps(dirty_rate); |
| @@ -665,7 +662,7 @@ TRACE_EVENT(balance_dirty_pages, · 58 unmodified lines | ||
| 665 | 662 | |
| 666 | 663 | TP_fast_assign( |
| 667 | 664 | unsigned long freerun = (thresh + bg_thresh) / 2; |
| 668 | − strscpy_pad(__entry->bdi, dev_name(wb->bdi->dev), 32); | |
| 665 | + strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32); | |
| 669 | 666 | |
| 670 | 667 | __entry->limit = global_wb_domain.dirty_limit; |
| 671 | 668 | __entry->setpoint = (global_wb_domain.dirty_limit + |
| @@ -726,7 +723,7 @@ TRACE_EVENT(writeback_sb_inodes_requeue, · 54 unmodified lines | ||
| 726 | 723 | |
| 727 | 724 | TP_fast_assign( |
| 728 | 725 | strscpy_pad(__entry->name, |
| 729 | − dev_name(inode_to_bdi(inode)->dev), 32); | |
| 726 | + bdi_dev_name(inode_to_bdi(inode)), 32); | |
| 730 | 727 | __entry->ino = inode->i_ino; |
| 731 | 728 | __entry->state = inode->i_state; |
| 732 | 729 | __entry->dirtied_when = inode->dirtied_when; |
| @@ -800,7 +797,7 @@ DECLARE_EVENT_CLASS(writeback_single_inode_template, · 67 unmodified lines | ||
| 800 | 797 | |
| 801 | 798 | TP_fast_assign( |
| 802 | 799 | strscpy_pad(__entry->name, |
| 803 | − dev_name(inode_to_bdi(inode)->dev), 32); | |
| 800 | + bdi_dev_name(inode_to_bdi(inode)), 32); | |
| 804 | 801 | __entry->ino = inode->i_ino; |
| 805 | 802 | __entry->state = inode->i_state; |
| 806 | 803 | __entry->dirtied_when = inode->dirtied_when; |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #include <linux/types.h> |
| 6 | 6 | #include <linux/compiler.h> |
| 7 | +#include <asm/bitsperlong.h> | |
| 7 | 8 | #include <asm/swab.h> |
| 8 | 9 | |
| 9 | 10 | /* |
| @@ -132,6 +133,15 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val) · 122 unmodified lines | ||
| 132 | 133 | __fswab64(x)) |
| 133 | 134 | #endif |
| 134 | 135 | |
| 136 | +static __always_inline unsigned long __swab(const unsigned long y) | |
| 137 | +{ | |
| 138 | +#if BITS_PER_LONG == 64 | |
| 139 | + return __swab64(y); | |
| 140 | +#else /* BITS_PER_LONG == 32 */ | |
| 141 | + return __swab32(y); | |
| 142 | +#endif | |
| 143 | +} | |
| 144 | + | |
| 135 | 145 | /** |
| 136 | 146 | * __swahw32 - return a word-swapped 32-bit value |
| 137 | 147 | * @x: value to wordswap |
| @@ -195,7 +195,7 @@ enum · 194 unmodified lines | ||
| 195 | 195 | VM_MIN_UNMAPPED=32, /* Set min percent of unmapped pages */ |
| 196 | 196 | VM_PANIC_ON_OOM=33, /* panic at out-of-memory */ |
| 197 | 197 | VM_VDSO_ENABLED=34, /* map VDSO into new processes? */ |
| 198 | − VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */ | |
| 198 | + VM_MIN_SLAB=35, /* Percent pages ignored by node reclaim */ | |
| 199 | 199 | }; |
| 200 | 200 | |
| 201 | 201 | |
| @@ -246,8 +246,7 @@ static int __init loglevel(char *str) · 245 unmodified lines | ||
| 246 | 246 | early_param("loglevel", loglevel); |
| 247 | 247 | |
| 248 | 248 | /* Change NUL term back to "=", to make "param" the whole string. */ |
| 249 | −static int __init repair_env_string(char *param, char *val, | |
| 250 | − const char *unused, void *arg) | |
| 249 | +static void __init repair_env_string(char *param, char *val) | |
| 251 | 250 | { |
| 252 | 251 | if (val) { |
| 253 | 252 | /* param=val or param="val"? */ |
| @@ -256,11 +255,9 @@ static int __init repair_env_string(char *param, char *val, · 2 unmodified lines | ||
| 256 | 255 | else if (val == param+strlen(param)+2) { |
| 257 | 256 | val[-2] = '='; |
| 258 | 257 | memmove(val-1, val, strlen(val)+1); |
| 259 | − val--; | |
| 260 | 258 | } else |
| 261 | 259 | BUG(); |
| 262 | 260 | } |
| 263 | − return 0; | |
| 264 | 261 | } |
| 265 | 262 | |
| 266 | 263 | /* Anything after -- gets handed straight to init. */ |
| @@ -272,7 +269,7 @@ static int __init set_init_arg(char *param, char *val, · 5 unmodified lines | ||
| 272 | 269 | if (panic_later) |
| 273 | 270 | return 0; |
| 274 | 271 | |
| 275 | − repair_env_string(param, val, unused, NULL); | |
| 272 | + repair_env_string(param, val); | |
| 276 | 273 | |
| 277 | 274 | for (i = 0; argv_init[i]; i++) { |
| 278 | 275 | if (i == MAX_INIT_ARGS) { |
| @@ -292,14 +289,16 @@ static int __init set_init_arg(char *param, char *val, · 13 unmodified lines | ||
| 292 | 289 | static int __init unknown_bootoption(char *param, char *val, |
| 293 | 290 | const char *unused, void *arg) |
| 294 | 291 | { |
| 295 | − repair_env_string(param, val, unused, NULL); | |
| 292 | + size_t len = strlen(param); | |
| 293 | + | |
| 294 | + repair_env_string(param, val); | |
| 296 | 295 | |
| 297 | 296 | /* Handle obsolete-style parameters */ |
| 298 | 297 | if (obsolete_checksetup(param)) |
| 299 | 298 | return 0; |
| 300 | 299 | |
| 301 | 300 | /* Unused module parameter. */ |
| 302 | − if (strchr(param, '.') && (!val || strchr(param, '.') < val)) | |
| 301 | + if (strnchr(param, len, '.')) | |
| 303 | 302 | return 0; |
| 304 | 303 | |
| 305 | 304 | if (panic_later) |
| @@ -313,7 +312,7 @@ static int __init unknown_bootoption(char *param, char *val, · 7 unmodified lines | ||
| 313 | 312 | panic_later = "env"; |
| 314 | 313 | panic_param = param; |
| 315 | 314 | } |
| 316 | − if (!strncmp(param, envp_init[i], val - param)) | |
| 315 | + if (!strncmp(param, envp_init[i], len+1)) | |
| 317 | 316 | break; |
| 318 | 317 | } |
| 319 | 318 | envp_init[i] = param; |
| @@ -991,6 +990,12 @@ static const char *initcall_level_names[] __initdata = { · 671 unmodified lines | ||
| 991 | 990 | "late", |
| 992 | 991 | }; |
| 993 | 992 | |
| 993 | +static int __init ignore_unknown_bootoption(char *param, char *val, | |
| 994 | + const char *unused, void *arg) | |
| 995 | +{ | |
| 996 | + return 0; | |
| 997 | +} | |
| 998 | + | |
| 994 | 999 | static void __init do_initcall_level(int level) |
| 995 | 1000 | { |
| 996 | 1001 | initcall_entry_t *fn; |
| @@ -1000,7 +1005,7 @@ static void __init do_initcall_level(int level) · 3 unmodified lines | ||
| 1000 | 1005 | initcall_command_line, __start___param, |
| 1001 | 1006 | __stop___param - __start___param, |
| 1002 | 1007 | level, level, |
| 1003 | − NULL, &repair_env_string); | |
| 1008 | + NULL, ignore_unknown_bootoption); | |
| 1004 | 1009 | |
| 1005 | 1010 | trace_initcall_level(initcall_level_names[level]); |
| 1006 | 1011 | for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) |
| @@ -1043,8 +1048,16 @@ static void __init do_pre_smp_initcalls(void) · 36 unmodified lines | ||
| 1043 | 1048 | |
| 1044 | 1049 | static int run_init_process(const char *init_filename) |
| 1045 | 1050 | { |
| 1051 | + const char *const *p; | |
| 1052 | + | |
| 1046 | 1053 | argv_init[0] = init_filename; |
| 1047 | 1054 | pr_info("Run %s as init process\n", init_filename); |
| 1055 | + pr_debug(" with arguments:\n"); | |
| 1056 | + for (p = argv_init; *p; p++) | |
| 1057 | + pr_debug(" %s\n", *p); | |
| 1058 | + pr_debug(" with environment:\n"); | |
| 1059 | + for (p = envp_init; *p; p++) | |
| 1060 | + pr_debug(" %s\n", *p); | |
| 1048 | 1061 | return do_execve(getname_kernel(init_filename), |
| 1049 | 1062 | (const char __user *const __user *)argv_init, |
| 1050 | 1063 | (const char __user *const __user *)envp_init); |
| @@ -1091,6 +1104,11 @@ static void mark_readonly(void) · 40 unmodified lines | ||
| 1091 | 1104 | } else |
| 1092 | 1105 | pr_info("Kernel memory protection disabled.\n"); |
| 1093 | 1106 | } |
| 1107 | +#elif defined(CONFIG_ARCH_HAS_STRICT_KERNEL_RWX) | |
| 1108 | +static inline void mark_readonly(void) | |
| 1109 | +{ | |
| 1110 | + pr_warn("Kernel memory protection not selected by kernel config.\n"); | |
| 1111 | +} | |
| 1094 | 1112 | #else |
| 1095 | 1113 | static inline void mark_readonly(void) |
| 1096 | 1114 | { |
| @@ -27,6 +27,7 @@ KCOV_INSTRUMENT_softirq.o := n · 26 unmodified lines | ||
| 27 | 27 | # and produce insane amounts of uninteresting coverage. |
| 28 | 28 | KCOV_INSTRUMENT_module.o := n |
| 29 | 29 | KCOV_INSTRUMENT_extable.o := n |
| 30 | +KCOV_INSTRUMENT_stacktrace.o := n | |
| 30 | 31 | # Don't self-instrument. |
| 31 | 32 | KCOV_INSTRUMENT_kcov.o := n |
| 32 | 33 | KASAN_SANITIZE_kcov.o := n |
| @@ -278,6 +278,13 @@ config ZLIB_DEFLATE · 277 unmodified lines | ||
| 278 | 278 | tristate |
| 279 | 279 | select BITREVERSE |
| 280 | 280 | |
| 281 | +config ZLIB_DFLTCC | |
| 282 | + def_bool y | |
| 283 | + depends on S390 | |
| 284 | + prompt "Enable s390x DEFLATE CONVERSION CALL support for kernel zlib" | |
| 285 | + help | |
| 286 | + Enable s390x hardware support for zlib in the kernel. | |
| 287 | + | |
| 281 | 288 | config LZO_COMPRESS |
| 282 | 289 | tristate |
| 283 | 290 | |
| @@ -16,6 +16,7 @@ KCOV_INSTRUMENT_rbtree.o := n · 15 unmodified lines | ||
| 16 | 16 | KCOV_INSTRUMENT_list_debug.o := n |
| 17 | 17 | KCOV_INSTRUMENT_debugobjects.o := n |
| 18 | 18 | KCOV_INSTRUMENT_dynamic_debug.o := n |
| 19 | +KCOV_INSTRUMENT_fault-inject.o := n | |
| 19 | 20 | |
| 20 | 21 | # Early boot use of cmdline, don't instrument it |
| 21 | 22 | ifdef CONFIG_AMD_MEM_ENCRYPT |
| @@ -140,6 +141,7 @@ obj-$(CONFIG_842_COMPRESS) += 842/ · 118 unmodified lines | ||
| 140 | 141 | obj-$(CONFIG_842_DECOMPRESS) += 842/ |
| 141 | 142 | obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ |
| 142 | 143 | obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ |
| 144 | +obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc/ | |
| 143 | 145 | obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ |
| 144 | 146 | obj-$(CONFIG_BCH) += bch.o |
| 145 | 147 | obj-$(CONFIG_LZO_COMPRESS) += lzo/ |
| @@ -10,6 +10,10 @@ · 9 unmodified lines | ||
| 10 | 10 | #include "zlib_inflate/inftrees.c" |
| 11 | 11 | #include "zlib_inflate/inffast.c" |
| 12 | 12 | #include "zlib_inflate/inflate.c" |
| 13 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 14 | +#include "zlib_dfltcc/dfltcc.c" | |
| 15 | +#include "zlib_dfltcc/dfltcc_inflate.c" | |
| 16 | +#endif | |
| 13 | 17 | |
| 14 | 18 | #else /* STATIC */ |
| 15 | 19 | /* initramfs et al: linked */ |
| @@ -76,7 +80,12 @@ STATIC int INIT __gunzip(unsigned char *buf, long len, · 60 unmodified lines | ||
| 76 | 80 | } |
| 77 | 81 | |
| 78 | 82 | strm->workspace = malloc(flush ? zlib_inflate_workspacesize() : |
| 83 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 84 | + /* Always allocate the full workspace for DFLTCC */ | |
| 85 | + zlib_inflate_workspacesize()); | |
| 86 | +#else | |
| 79 | 87 | sizeof(struct inflate_state)); |
| 88 | +#endif | |
| 80 | 89 | if (strm->workspace == NULL) { |
| 81 | 90 | error("Out of memory while allocating workspace"); |
| 82 | 91 | goto gunzip_nomem4; |
| @@ -123,10 +132,14 @@ STATIC int INIT __gunzip(unsigned char *buf, long len, · 40 unmodified lines | ||
| 123 | 132 | |
| 124 | 133 | rc = zlib_inflateInit2(strm, -MAX_WBITS); |
| 125 | 134 | |
| 135 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 136 | + /* Always keep the window for DFLTCC */ | |
| 137 | +#else | |
| 126 | 138 | if (!flush) { |
| 127 | 139 | WS(strm)->inflate_state.wsize = 0; |
| 128 | 140 | WS(strm)->inflate_state.window = NULL; |
| 129 | 141 | } |
| 142 | +#endif | |
| 130 | 143 | |
| 131 | 144 | while (rc == Z_OK) { |
| 132 | 145 | if (strm->avail_in == 0) { |
| @@ -17,9 +17,9 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/export.h> |
| 18 | 18 | #include <linux/kernel.h> |
| 19 | 19 | |
| 20 | −#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \ | |
| 21 | − !defined(find_next_and_bit) | |
| 22 | − | |
| 20 | +#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \ | |
| 21 | + !defined(find_next_bit_le) || !defined(find_next_zero_bit_le) || \ | |
| 22 | + !defined(find_next_and_bit) | |
| 23 | 23 | /* |
| 24 | 24 | * This is a common helper function for find_next_bit, find_next_zero_bit, and |
| 25 | 25 | * find_next_and_bit. The differences are: |
| @@ -27,11 +27,11 @@ · 1 unmodified line | ||
| 27 | 27 | * searching it for one bits. |
| 28 | 28 | * - The optional "addr2", which is anded with "addr1" if present. |
| 29 | 29 | */ |
| 30 | −static inline unsigned long _find_next_bit(const unsigned long *addr1, | |
| 30 | +static unsigned long _find_next_bit(const unsigned long *addr1, | |
| 31 | 31 | const unsigned long *addr2, unsigned long nbits, |
| 32 | − unsigned long start, unsigned long invert) | |
| 32 | + unsigned long start, unsigned long invert, unsigned long le) | |
| 33 | 33 | { |
| 34 | − unsigned long tmp; | |
| 34 | + unsigned long tmp, mask; | |
| 35 | 35 | |
| 36 | 36 | if (unlikely(start >= nbits)) |
| 37 | 37 | return nbits; |
| @@ -42,7 +42,12 @@ static inline unsigned long _find_next_bit(const unsigned long *addr1, · 4 unmodified lines | ||
| 42 | 42 | tmp ^= invert; |
| 43 | 43 | |
| 44 | 44 | /* Handle 1st word. */ |
| 45 | − tmp &= BITMAP_FIRST_WORD_MASK(start); | |
| 45 | + mask = BITMAP_FIRST_WORD_MASK(start); | |
| 46 | + if (le) | |
| 47 | + mask = swab(mask); | |
| 48 | + | |
| 49 | + tmp &= mask; | |
| 50 | + | |
| 46 | 51 | start = round_down(start, BITS_PER_LONG); |
| 47 | 52 | |
| 48 | 53 | while (!tmp) { |
| @@ -56,6 +61,9 @@ static inline unsigned long _find_next_bit(const unsigned long *addr1, · 7 unmodified lines | ||
| 56 | 61 | tmp ^= invert; |
| 57 | 62 | } |
| 58 | 63 | |
| 64 | + if (le) | |
| 65 | + tmp = swab(tmp); | |
| 66 | + | |
| 59 | 67 | return min(start + __ffs(tmp), nbits); |
| 60 | 68 | } |
| 61 | 69 | #endif |
| @@ -67,7 +75,7 @@ static inline unsigned long _find_next_bit(const unsigned long *addr1, · 5 unmodified lines | ||
| 67 | 75 | unsigned long find_next_bit(const unsigned long *addr, unsigned long size, |
| 68 | 76 | unsigned long offset) |
| 69 | 77 | { |
| 70 | − return _find_next_bit(addr, NULL, size, offset, 0UL); | |
| 78 | + return _find_next_bit(addr, NULL, size, offset, 0UL, 0); | |
| 71 | 79 | } |
| 72 | 80 | EXPORT_SYMBOL(find_next_bit); |
| 73 | 81 | #endif |
| @@ -76,7 +84,7 @@ EXPORT_SYMBOL(find_next_bit); · 2 unmodified lines | ||
| 76 | 84 | unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, |
| 77 | 85 | unsigned long offset) |
| 78 | 86 | { |
| 79 | − return _find_next_bit(addr, NULL, size, offset, ~0UL); | |
| 87 | + return _find_next_bit(addr, NULL, size, offset, ~0UL, 0); | |
| 80 | 88 | } |
| 81 | 89 | EXPORT_SYMBOL(find_next_zero_bit); |
| 82 | 90 | #endif |
| @@ -86,7 +94,7 @@ unsigned long find_next_and_bit(const unsigned long *addr1, · 3 unmodified lines | ||
| 86 | 94 | const unsigned long *addr2, unsigned long size, |
| 87 | 95 | unsigned long offset) |
| 88 | 96 | { |
| 89 | − return _find_next_bit(addr1, addr2, size, offset, 0UL); | |
| 97 | + return _find_next_bit(addr1, addr2, size, offset, 0UL, 0); | |
| 90 | 98 | } |
| 91 | 99 | EXPORT_SYMBOL(find_next_and_bit); |
| 92 | 100 | #endif |
| @@ -149,57 +157,11 @@ EXPORT_SYMBOL(find_last_bit); · 56 unmodified lines | ||
| 149 | 157 | |
| 150 | 158 | #ifdef __BIG_ENDIAN |
| 151 | 159 | |
| 152 | −/* include/linux/byteorder does not support "unsigned long" type */ | |
| 153 | −static inline unsigned long ext2_swab(const unsigned long y) | |
| 154 | −{ | |
| 155 | −#if BITS_PER_LONG == 64 | |
| 156 | − return (unsigned long) __swab64((u64) y); | |
| 157 | −#elif BITS_PER_LONG == 32 | |
| 158 | − return (unsigned long) __swab32((u32) y); | |
| 159 | −#else | |
| 160 | −#error BITS_PER_LONG not defined | |
| 161 | −#endif | |
| 162 | −} | |
| 163 | − | |
| 164 | −#if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le) | |
| 165 | −static inline unsigned long _find_next_bit_le(const unsigned long *addr1, | |
| 166 | − const unsigned long *addr2, unsigned long nbits, | |
| 167 | − unsigned long start, unsigned long invert) | |
| 168 | −{ | |
| 169 | − unsigned long tmp; | |
| 170 | − | |
| 171 | − if (unlikely(start >= nbits)) | |
| 172 | − return nbits; | |
| 173 | − | |
| 174 | − tmp = addr1[start / BITS_PER_LONG]; | |
| 175 | − if (addr2) | |
| 176 | − tmp &= addr2[start / BITS_PER_LONG]; | |
| 177 | − tmp ^= invert; | |
| 178 | − | |
| 179 | − /* Handle 1st word. */ | |
| 180 | − tmp &= ext2_swab(BITMAP_FIRST_WORD_MASK(start)); | |
| 181 | − start = round_down(start, BITS_PER_LONG); | |
| 182 | − | |
| 183 | − while (!tmp) { | |
| 184 | − start += BITS_PER_LONG; | |
| 185 | − if (start >= nbits) | |
| 186 | − return nbits; | |
| 187 | − | |
| 188 | − tmp = addr1[start / BITS_PER_LONG]; | |
| 189 | − if (addr2) | |
| 190 | − tmp &= addr2[start / BITS_PER_LONG]; | |
| 191 | − tmp ^= invert; | |
| 192 | − } | |
| 193 | − | |
| 194 | − return min(start + __ffs(ext2_swab(tmp)), nbits); | |
| 195 | −} | |
| 196 | −#endif | |
| 197 | − | |
| 198 | 160 | #ifndef find_next_zero_bit_le |
| 199 | 161 | unsigned long find_next_zero_bit_le(const void *addr, unsigned |
| 200 | 162 | long size, unsigned long offset) |
| 201 | 163 | { |
| 202 | − return _find_next_bit_le(addr, NULL, size, offset, ~0UL); | |
| 164 | + return _find_next_bit(addr, NULL, size, offset, ~0UL, 1); | |
| 203 | 165 | } |
| 204 | 166 | EXPORT_SYMBOL(find_next_zero_bit_le); |
| 205 | 167 | #endif |
| @@ -208,7 +170,7 @@ EXPORT_SYMBOL(find_next_zero_bit_le); · 2 unmodified lines | ||
| 208 | 170 | unsigned long find_next_bit_le(const void *addr, unsigned |
| 209 | 171 | long size, unsigned long offset) |
| 210 | 172 | { |
| 211 | − return _find_next_bit_le(addr, NULL, size, offset, 0UL); | |
| 173 | + return _find_next_bit(addr, NULL, size, offset, 0UL, 1); | |
| 212 | 174 | } |
| 213 | 175 | EXPORT_SYMBOL(find_next_bit_le); |
| 214 | 176 | #endif |
| @@ -311,7 +311,7 @@ int __sg_alloc_table(struct sg_table *table, unsigned int nents, · 310 unmodified lines | ||
| 311 | 311 | if (prv) |
| 312 | 312 | table->nents = ++table->orig_nents; |
| 313 | 313 | |
| 314 | − return -ENOMEM; | |
| 314 | + return -ENOMEM; | |
| 315 | 315 | } |
| 316 | 316 | |
| 317 | 317 | sg_init_table(sg, alloc_size); |
| @@ -275,22 +275,23 @@ static void __init test_copy(void) · 274 unmodified lines | ||
| 275 | 275 | static void __init test_replace(void) |
| 276 | 276 | { |
| 277 | 277 | unsigned int nbits = 64; |
| 278 | + unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG); | |
| 278 | 279 | DECLARE_BITMAP(bmap, 1024); |
| 279 | 280 | |
| 280 | 281 | bitmap_zero(bmap, 1024); |
| 281 | − bitmap_replace(bmap, &exp2[0], &exp2[1], exp2_to_exp3_mask, nbits); | |
| 282 | + bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits); | |
| 282 | 283 | expect_eq_bitmap(bmap, exp3_0_1, nbits); |
| 283 | 284 | |
| 284 | 285 | bitmap_zero(bmap, 1024); |
| 285 | − bitmap_replace(bmap, &exp2[1], &exp2[0], exp2_to_exp3_mask, nbits); | |
| 286 | + bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits); | |
| 286 | 287 | expect_eq_bitmap(bmap, exp3_1_0, nbits); |
| 287 | 288 | |
| 288 | 289 | bitmap_fill(bmap, 1024); |
| 289 | − bitmap_replace(bmap, &exp2[0], &exp2[1], exp2_to_exp3_mask, nbits); | |
| 290 | + bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits); | |
| 290 | 291 | expect_eq_bitmap(bmap, exp3_0_1, nbits); |
| 291 | 292 | |
| 292 | 293 | bitmap_fill(bmap, 1024); |
| 293 | − bitmap_replace(bmap, &exp2[1], &exp2[0], exp2_to_exp3_mask, nbits); | |
| 294 | + bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits); | |
| 294 | 295 | expect_eq_bitmap(bmap, exp3_1_0, nbits); |
| 295 | 296 | } |
| 296 | 297 | |
| @@ -158,6 +158,7 @@ static noinline void __init kmalloc_oob_krealloc_more(void) · 157 unmodified lines | ||
| 158 | 158 | if (!ptr1 || !ptr2) { |
| 159 | 159 | pr_err("Allocation failed\n"); |
| 160 | 160 | kfree(ptr1); |
| 161 | + kfree(ptr2); | |
| 161 | 162 | return; |
| 162 | 163 | } |
| 163 | 164 | |
| @@ -52,16 +52,19 @@ · 51 unmodified lines | ||
| 52 | 52 | #include <linux/zutil.h> |
| 53 | 53 | #include "defutil.h" |
| 54 | 54 | |
| 55 | +/* architecture-specific bits */ | |
| 56 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 57 | +# include "../zlib_dfltcc/dfltcc.h" | |
| 58 | +#else | |
| 59 | +#define DEFLATE_RESET_HOOK(strm) do {} while (0) | |
| 60 | +#define DEFLATE_HOOK(strm, flush, bstate) 0 | |
| 61 | +#define DEFLATE_NEED_CHECKSUM(strm) 1 | |
| 62 | +#define DEFLATE_DFLTCC_ENABLED() 0 | |
| 63 | +#endif | |
| 55 | 64 | |
| 56 | 65 | /* =========================================================================== |
| 57 | 66 | * Function prototypes. |
| 58 | 67 | */ |
| 59 | −typedef enum { | |
| 60 | − need_more, /* block not completed, need more input or more output */ | |
| 61 | − block_done, /* block flush performed */ | |
| 62 | − finish_started, /* finish started, need only more output at next deflate */ | |
| 63 | − finish_done /* finish done, accept no more input or output */ | |
| 64 | −} block_state; | |
| 65 | 68 | |
| 66 | 69 | typedef block_state (*compress_func) (deflate_state *s, int flush); |
| 67 | 70 | /* Compression function. Returns the block state after the call. */ |
| @@ -72,7 +75,6 @@ static block_state deflate_fast (deflate_state *s, int flush); · 4 unmodified lines | ||
| 72 | 75 | static block_state deflate_slow (deflate_state *s, int flush); |
| 73 | 76 | static void lm_init (deflate_state *s); |
| 74 | 77 | static void putShortMSB (deflate_state *s, uInt b); |
| 75 | −static void flush_pending (z_streamp strm); | |
| 76 | 78 | static int read_buf (z_streamp strm, Byte *buf, unsigned size); |
| 77 | 79 | static uInt longest_match (deflate_state *s, IPos cur_match); |
| 78 | 80 | |
| @@ -98,6 +100,25 @@ static void check_match (deflate_state *s, IPos start, IPos match, · 19 unmodified lines | ||
| 98 | 100 | * See deflate.c for comments about the MIN_MATCH+1. |
| 99 | 101 | */ |
| 100 | 102 | |
| 103 | +/* Workspace to be allocated for deflate processing */ | |
| 104 | +typedef struct deflate_workspace { | |
| 105 | + /* State memory for the deflator */ | |
| 106 | + deflate_state deflate_memory; | |
| 107 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 108 | + /* State memory for s390 hardware deflate */ | |
| 109 | + struct dfltcc_state dfltcc_memory; | |
| 110 | +#endif | |
| 111 | + Byte *window_memory; | |
| 112 | + Pos *prev_memory; | |
| 113 | + Pos *head_memory; | |
| 114 | + char *overlay_memory; | |
| 115 | +} deflate_workspace; | |
| 116 | + | |
| 117 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 118 | +/* dfltcc_state must be doubleword aligned for DFLTCC call */ | |
| 119 | +static_assert(offsetof(struct deflate_workspace, dfltcc_memory) % 8 == 0); | |
| 120 | +#endif | |
| 121 | + | |
| 101 | 122 | /* Values for max_lazy_match, good_match and max_chain_length, depending on |
| 102 | 123 | * the desired pack level (0..9). The values given below have been tuned to |
| 103 | 124 | * exclude worst case performance for pathological files. Better values may be |
| @@ -207,7 +228,15 @@ int zlib_deflateInit2( · 103 unmodified lines | ||
| 207 | 228 | */ |
| 208 | 229 | next = (char *) mem; |
| 209 | 230 | next += sizeof(*mem); |
| 231 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 232 | + /* | |
| 233 | + * DFLTCC requires the window to be page aligned. | |
| 234 | + * Thus, we overallocate and take the aligned portion of the buffer. | |
| 235 | + */ | |
| 236 | + mem->window_memory = (Byte *) PTR_ALIGN(next, PAGE_SIZE); | |
| 237 | +#else | |
| 210 | 238 | mem->window_memory = (Byte *) next; |
| 239 | +#endif | |
| 211 | 240 | next += zlib_deflate_window_memsize(windowBits); |
| 212 | 241 | mem->prev_memory = (Pos *) next; |
| 213 | 242 | next += zlib_deflate_prev_memsize(windowBits); |
| @@ -277,6 +306,8 @@ int zlib_deflateReset( · 63 unmodified lines | ||
| 277 | 306 | zlib_tr_init(s); |
| 278 | 307 | lm_init(s); |
| 279 | 308 | |
| 309 | + DEFLATE_RESET_HOOK(strm); | |
| 310 | + | |
| 280 | 311 | return Z_OK; |
| 281 | 312 | } |
| 282 | 313 | |
| @@ -294,35 +325,6 @@ static void putShortMSB( · 11 unmodified lines | ||
| 294 | 325 | put_byte(s, (Byte)(b & 0xff)); |
| 295 | 326 | } |
| 296 | 327 | |
| 297 | −/* ========================================================================= | |
| 298 | − * Flush as much pending output as possible. All deflate() output goes | |
| 299 | − * through this function so some applications may wish to modify it | |
| 300 | − * to avoid allocating a large strm->next_out buffer and copying into it. | |
| 301 | − * (See also read_buf()). | |
| 302 | − */ | |
| 303 | −static void flush_pending( | |
| 304 | − z_streamp strm | |
| 305 | −) | |
| 306 | −{ | |
| 307 | − deflate_state *s = (deflate_state *) strm->state; | |
| 308 | − unsigned len = s->pending; | |
| 309 | − | |
| 310 | − if (len > strm->avail_out) len = strm->avail_out; | |
| 311 | − if (len == 0) return; | |
| 312 | − | |
| 313 | − if (strm->next_out != NULL) { | |
| 314 | − memcpy(strm->next_out, s->pending_out, len); | |
| 315 | − strm->next_out += len; | |
| 316 | − } | |
| 317 | − s->pending_out += len; | |
| 318 | − strm->total_out += len; | |
| 319 | − strm->avail_out -= len; | |
| 320 | − s->pending -= len; | |
| 321 | − if (s->pending == 0) { | |
| 322 | − s->pending_out = s->pending_buf; | |
| 323 | − } | |
| 324 | −} | |
| 325 | − | |
| 326 | 328 | /* ========================================================================= */ |
| 327 | 329 | int zlib_deflate( |
| 328 | 330 | z_streamp strm, |
| @@ -404,7 +406,8 @@ int zlib_deflate( · 75 unmodified lines | ||
| 404 | 406 | (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { |
| 405 | 407 | block_state bstate; |
| 406 | 408 | |
| 407 | − bstate = (*(configuration_table[s->level].func))(s, flush); | |
| 409 | + bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : | |
| 410 | + (*(configuration_table[s->level].func))(s, flush); | |
| 408 | 411 | |
| 409 | 412 | if (bstate == finish_started || bstate == finish_done) { |
| 410 | 413 | s->status = FINISH_STATE; |
| @@ -503,7 +506,8 @@ static int read_buf( · 92 unmodified lines | ||
| 503 | 506 | |
| 504 | 507 | strm->avail_in -= len; |
| 505 | 508 | |
| 506 | − if (!((deflate_state *)(strm->state))->noheader) { | |
| 509 | + if (!DEFLATE_NEED_CHECKSUM(strm)) {} | |
| 510 | + else if (!((deflate_state *)(strm->state))->noheader) { | |
| 507 | 511 | strm->adler = zlib_adler32(strm->adler, strm->next_in, len); |
| 508 | 512 | } |
| 509 | 513 | memcpy(buf, strm->next_in, len); |
| @@ -1135,3 +1139,8 @@ int zlib_deflate_workspacesize(int windowBits, int memLevel) · 625 unmodified lines | ||
| 1135 | 1139 | + zlib_deflate_head_memsize(memLevel) |
| 1136 | 1140 | + zlib_deflate_overlay_memsize(memLevel); |
| 1137 | 1141 | } |
| 1142 | + | |
| 1143 | +int zlib_deflate_dfltcc_enabled(void) | |
| 1144 | +{ | |
| 1145 | + return DEFLATE_DFLTCC_ENABLED(); | |
| 1146 | +} | |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/zlib.h> |
| 13 | 13 | |
| 14 | 14 | EXPORT_SYMBOL(zlib_deflate_workspacesize); |
| 15 | +EXPORT_SYMBOL(zlib_deflate_dfltcc_enabled); | |
| 15 | 16 | EXPORT_SYMBOL(zlib_deflate); |
| 16 | 17 | EXPORT_SYMBOL(zlib_deflateInit2); |
| 17 | 18 | EXPORT_SYMBOL(zlib_deflateEnd); |
| @@ -76,11 +76,6 @@ static const uch bl_order[BL_CODES] · 75 unmodified lines | ||
| 76 | 76 | * probability, to avoid transmitting the lengths for unused bit length codes. |
| 77 | 77 | */ |
| 78 | 78 | |
| 79 | −#define Buf_size (8 * 2*sizeof(char)) | |
| 80 | −/* Number of bits used within bi_buf. (bi_buf might be implemented on | |
| 81 | − * more than 16 bits on some systems.) | |
| 82 | − */ | |
| 83 | − | |
| 84 | 79 | /* =========================================================================== |
| 85 | 80 | * Local data. These are initialized only once. |
| 86 | 81 | */ |
| @@ -147,7 +142,6 @@ static void send_all_trees (deflate_state *s, int lcodes, int dcodes, · 60 unmodified lines | ||
| 147 | 142 | static void compress_block (deflate_state *s, ct_data *ltree, |
| 148 | 143 | ct_data *dtree); |
| 149 | 144 | static void set_data_type (deflate_state *s); |
| 150 | −static void bi_windup (deflate_state *s); | |
| 151 | 145 | static void bi_flush (deflate_state *s); |
| 152 | 146 | static void copy_block (deflate_state *s, char *buf, unsigned len, |
| 153 | 147 | int header); |
| @@ -169,54 +163,6 @@ static void copy_block (deflate_state *s, char *buf, unsigned len, · 15 unmodified lines | ||
| 169 | 163 | * used. |
| 170 | 164 | */ |
| 171 | 165 | |
| 172 | −/* =========================================================================== | |
| 173 | − * Send a value on a given number of bits. | |
| 174 | − * IN assertion: length <= 16 and value fits in length bits. | |
| 175 | − */ | |
| 176 | −#ifdef DEBUG_ZLIB | |
| 177 | −static void send_bits (deflate_state *s, int value, int length); | |
| 178 | − | |
| 179 | −static void send_bits( | |
| 180 | − deflate_state *s, | |
| 181 | − int value, /* value to send */ | |
| 182 | − int length /* number of bits */ | |
| 183 | −) | |
| 184 | −{ | |
| 185 | − Tracevv((stderr," l %2d v %4x ", length, value)); | |
| 186 | − Assert(length > 0 && length <= 15, "invalid length"); | |
| 187 | − s->bits_sent += (ulg)length; | |
| 188 | − | |
| 189 | − /* If not enough room in bi_buf, use (valid) bits from bi_buf and | |
| 190 | − * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) | |
| 191 | − * unused bits in value. | |
| 192 | − */ | |
| 193 | − if (s->bi_valid > (int)Buf_size - length) { | |
| 194 | − s->bi_buf |= (value << s->bi_valid); | |
| 195 | − put_short(s, s->bi_buf); | |
| 196 | − s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); | |
| 197 | − s->bi_valid += length - Buf_size; | |
| 198 | − } else { | |
| 199 | − s->bi_buf |= value << s->bi_valid; | |
| 200 | − s->bi_valid += length; | |
| 201 | − } | |
| 202 | −} | |
| 203 | −#else /* !DEBUG_ZLIB */ | |
| 204 | − | |
| 205 | −#define send_bits(s, value, length) \ | |
| 206 | −{ int len = length;\ | |
| 207 | − if (s->bi_valid > (int)Buf_size - len) {\ | |
| 208 | − int val = value;\ | |
| 209 | − s->bi_buf |= (val << s->bi_valid);\ | |
| 210 | − put_short(s, s->bi_buf);\ | |
| 211 | − s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ | |
| 212 | − s->bi_valid += len - Buf_size;\ | |
| 213 | − } else {\ | |
| 214 | − s->bi_buf |= (value) << s->bi_valid;\ | |
| 215 | − s->bi_valid += len;\ | |
| 216 | − }\ | |
| 217 | −} | |
| 218 | −#endif /* DEBUG_ZLIB */ | |
| 219 | − | |
| 220 | 166 | /* =========================================================================== |
| 221 | 167 | * Initialize the various 'constant' tables. In a multi-threaded environment, |
| 222 | 168 | * this function may be called by two threads concurrently, but this is |
| @@ -1,5 +1,7 @@ | ||
| 1 | +#ifndef DEFUTIL_H | |
| 2 | +#define DEFUTIL_H | |
| 1 | 3 | |
| 2 | − | |
| 4 | +#include <linux/zutil.h> | |
| 3 | 5 | |
| 4 | 6 | #define Assert(err, str) |
| 5 | 7 | #define Trace(dummy) |
| @@ -238,17 +240,13 @@ typedef struct deflate_state { · 232 unmodified lines | ||
| 238 | 240 | |
| 239 | 241 | } deflate_state; |
| 240 | 242 | |
| 241 | −typedef struct deflate_workspace { | |
| 242 | − /* State memory for the deflator */ | |
| 243 | − deflate_state deflate_memory; | |
| 244 | − Byte *window_memory; | |
| 245 | − Pos *prev_memory; | |
| 246 | − Pos *head_memory; | |
| 247 | − char *overlay_memory; | |
| 248 | −} deflate_workspace; | |
| 249 | − | |
| 243 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 244 | +#define zlib_deflate_window_memsize(windowBits) \ | |
| 245 | + (2 * (1 << (windowBits)) * sizeof(Byte) + PAGE_SIZE) | |
| 246 | +#else | |
| 250 | 247 | #define zlib_deflate_window_memsize(windowBits) \ |
| 251 | 248 | (2 * (1 << (windowBits)) * sizeof(Byte)) |
| 249 | +#endif | |
| 252 | 250 | #define zlib_deflate_prev_memsize(windowBits) \ |
| 253 | 251 | ((1 << (windowBits)) * sizeof(Pos)) |
| 254 | 252 | #define zlib_deflate_head_memsize(memLevel) \ |
| @@ -292,6 +290,24 @@ void zlib_tr_stored_type_only (deflate_state *); · 37 unmodified lines | ||
| 292 | 290 | put_byte(s, (uch)((ush)(w) >> 8)); \ |
| 293 | 291 | } |
| 294 | 292 | |
| 293 | +/* =========================================================================== | |
| 294 | + * Reverse the first len bits of a code, using straightforward code (a faster | |
| 295 | + * method would use a table) | |
| 296 | + * IN assertion: 1 <= len <= 15 | |
| 297 | + */ | |
| 298 | +static inline unsigned bi_reverse( | |
| 299 | + unsigned code, /* the value to invert */ | |
| 300 | + int len /* its bit length */ | |
| 301 | +) | |
| 302 | +{ | |
| 303 | + register unsigned res = 0; | |
| 304 | + do { | |
| 305 | + res |= code & 1; | |
| 306 | + code >>= 1, res <<= 1; | |
| 307 | + } while (--len > 0); | |
| 308 | + return res >> 1; | |
| 309 | +} | |
| 310 | + | |
| 295 | 311 | /* =========================================================================== |
| 296 | 312 | * Flush the bit buffer, keeping at most 7 bits in it. |
| 297 | 313 | */ |
| @@ -325,3 +341,101 @@ static inline void bi_windup(deflate_state *s) · 27 unmodified lines | ||
| 325 | 341 | #endif |
| 326 | 342 | } |
| 327 | 343 | |
| 344 | +typedef enum { | |
| 345 | + need_more, /* block not completed, need more input or more output */ | |
| 346 | + block_done, /* block flush performed */ | |
| 347 | + finish_started, /* finish started, need only more output at next deflate */ | |
| 348 | + finish_done /* finish done, accept no more input or output */ | |
| 349 | +} block_state; | |
| 350 | + | |
| 351 | +#define Buf_size (8 * 2*sizeof(char)) | |
| 352 | +/* Number of bits used within bi_buf. (bi_buf might be implemented on | |
| 353 | + * more than 16 bits on some systems.) | |
| 354 | + */ | |
| 355 | + | |
| 356 | +/* =========================================================================== | |
| 357 | + * Send a value on a given number of bits. | |
| 358 | + * IN assertion: length <= 16 and value fits in length bits. | |
| 359 | + */ | |
| 360 | +#ifdef DEBUG_ZLIB | |
| 361 | +static void send_bits (deflate_state *s, int value, int length); | |
| 362 | + | |
| 363 | +static void send_bits( | |
| 364 | + deflate_state *s, | |
| 365 | + int value, /* value to send */ | |
| 366 | + int length /* number of bits */ | |
| 367 | +) | |
| 368 | +{ | |
| 369 | + Tracevv((stderr," l %2d v %4x ", length, value)); | |
| 370 | + Assert(length > 0 && length <= 15, "invalid length"); | |
| 371 | + s->bits_sent += (ulg)length; | |
| 372 | + | |
| 373 | + /* If not enough room in bi_buf, use (valid) bits from bi_buf and | |
| 374 | + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) | |
| 375 | + * unused bits in value. | |
| 376 | + */ | |
| 377 | + if (s->bi_valid > (int)Buf_size - length) { | |
| 378 | + s->bi_buf |= (value << s->bi_valid); | |
| 379 | + put_short(s, s->bi_buf); | |
| 380 | + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); | |
| 381 | + s->bi_valid += length - Buf_size; | |
| 382 | + } else { | |
| 383 | + s->bi_buf |= value << s->bi_valid; | |
| 384 | + s->bi_valid += length; | |
| 385 | + } | |
| 386 | +} | |
| 387 | +#else /* !DEBUG_ZLIB */ | |
| 388 | + | |
| 389 | +#define send_bits(s, value, length) \ | |
| 390 | +{ int len = length;\ | |
| 391 | + if (s->bi_valid > (int)Buf_size - len) {\ | |
| 392 | + int val = value;\ | |
| 393 | + s->bi_buf |= (val << s->bi_valid);\ | |
| 394 | + put_short(s, s->bi_buf);\ | |
| 395 | + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ | |
| 396 | + s->bi_valid += len - Buf_size;\ | |
| 397 | + } else {\ | |
| 398 | + s->bi_buf |= (value) << s->bi_valid;\ | |
| 399 | + s->bi_valid += len;\ | |
| 400 | + }\ | |
| 401 | +} | |
| 402 | +#endif /* DEBUG_ZLIB */ | |
| 403 | + | |
| 404 | +static inline void zlib_tr_send_bits( | |
| 405 | + deflate_state *s, | |
| 406 | + int value, | |
| 407 | + int length | |
| 408 | +) | |
| 409 | +{ | |
| 410 | + send_bits(s, value, length); | |
| 411 | +} | |
| 412 | + | |
| 413 | +/* ========================================================================= | |
| 414 | + * Flush as much pending output as possible. All deflate() output goes | |
| 415 | + * through this function so some applications may wish to modify it | |
| 416 | + * to avoid allocating a large strm->next_out buffer and copying into it. | |
| 417 | + * (See also read_buf()). | |
| 418 | + */ | |
| 419 | +static inline void flush_pending( | |
| 420 | + z_streamp strm | |
| 421 | +) | |
| 422 | +{ | |
| 423 | + deflate_state *s = (deflate_state *) strm->state; | |
| 424 | + unsigned len = s->pending; | |
| 425 | + | |
| 426 | + if (len > strm->avail_out) len = strm->avail_out; | |
| 427 | + if (len == 0) return; | |
| 428 | + | |
| 429 | + if (strm->next_out != NULL) { | |
| 430 | + memcpy(strm->next_out, s->pending_out, len); | |
| 431 | + strm->next_out += len; | |
| 432 | + } | |
| 433 | + s->pending_out += len; | |
| 434 | + strm->total_out += len; | |
| 435 | + strm->avail_out -= len; | |
| 436 | + s->pending -= len; | |
| 437 | + if (s->pending == 0) { | |
| 438 | + s->pending_out = s->pending_buf; | |
| 439 | + } | |
| 440 | +} | |
| 441 | +#endif /* DEFUTIL_H */ | |
| @@ -0,0 +1,11 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +# | |
| 3 | +# This is a modified version of zlib, which does all memory | |
| 4 | +# allocation ahead of time. | |
| 5 | +# | |
| 6 | +# This is the code for s390 zlib hardware support. | |
| 7 | +# | |
| 8 | + | |
| 9 | +obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc.o | |
| 10 | + | |
| 11 | +zlib_dfltcc-objs := dfltcc.o dfltcc_deflate.o dfltcc_inflate.o dfltcc_syms.o | |
| @@ -0,0 +1,55 @@ | ||
| 1 | +// SPDX-License-Identifier: Zlib | |
| 2 | +/* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */ | |
| 3 | + | |
| 4 | +#include <linux/zutil.h> | |
| 5 | +#include "dfltcc_util.h" | |
| 6 | +#include "dfltcc.h" | |
| 7 | + | |
| 8 | +char *oesc_msg( | |
| 9 | + char *buf, | |
| 10 | + int oesc | |
| 11 | +) | |
| 12 | +{ | |
| 13 | + if (oesc == 0x00) | |
| 14 | + return NULL; /* Successful completion */ | |
| 15 | + else { | |
| 16 | +#ifdef STATIC | |
| 17 | + return NULL; /* Ignore for pre-boot decompressor */ | |
| 18 | +#else | |
| 19 | + sprintf(buf, "Operation-Ending-Supplemental Code is 0x%.2X", oesc); | |
| 20 | + return buf; | |
| 21 | +#endif | |
| 22 | + } | |
| 23 | +} | |
| 24 | + | |
| 25 | +void dfltcc_reset( | |
| 26 | + z_streamp strm, | |
| 27 | + uInt size | |
| 28 | +) | |
| 29 | +{ | |
| 30 | + struct dfltcc_state *dfltcc_state = | |
| 31 | + (struct dfltcc_state *)((char *)strm->state + size); | |
| 32 | + struct dfltcc_qaf_param *param = | |
| 33 | + (struct dfltcc_qaf_param *)&dfltcc_state->param; | |
| 34 | + | |
| 35 | + /* Initialize available functions */ | |
| 36 | + if (is_dfltcc_enabled()) { | |
| 37 | + dfltcc(DFLTCC_QAF, param, NULL, NULL, NULL, NULL, NULL); | |
| 38 | + memmove(&dfltcc_state->af, param, sizeof(dfltcc_state->af)); | |
| 39 | + } else | |
| 40 | + memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); | |
| 41 | + | |
| 42 | + /* Initialize parameter block */ | |
| 43 | + memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param)); | |
| 44 | + dfltcc_state->param.nt = 1; | |
| 45 | + | |
| 46 | + /* Initialize tuning parameters */ | |
| 47 | + if (zlib_dfltcc_support == ZLIB_DFLTCC_FULL_DEBUG) | |
| 48 | + dfltcc_state->level_mask = DFLTCC_LEVEL_MASK_DEBUG; | |
| 49 | + else | |
| 50 | + dfltcc_state->level_mask = DFLTCC_LEVEL_MASK; | |
| 51 | + dfltcc_state->block_size = DFLTCC_BLOCK_SIZE; | |
| 52 | + dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE; | |
| 53 | + dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE; | |
| 54 | + dfltcc_state->param.ribm = DFLTCC_RIBM; | |
| 55 | +} | |
| @@ -0,0 +1,155 @@ | ||
| 1 | +// SPDX-License-Identifier: Zlib | |
| 2 | +#ifndef DFLTCC_H | |
| 3 | +#define DFLTCC_H | |
| 4 | + | |
| 5 | +#include "../zlib_deflate/defutil.h" | |
| 6 | +#include <asm/facility.h> | |
| 7 | +#include <asm/setup.h> | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * Tuning parameters. | |
| 11 | + */ | |
| 12 | +#define DFLTCC_LEVEL_MASK 0x2 /* DFLTCC compression for level 1 only */ | |
| 13 | +#define DFLTCC_LEVEL_MASK_DEBUG 0x3fe /* DFLTCC compression for all levels */ | |
| 14 | +#define DFLTCC_BLOCK_SIZE 1048576 | |
| 15 | +#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096 | |
| 16 | +#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096 | |
| 17 | +#define DFLTCC_RIBM 0 | |
| 18 | + | |
| 19 | +#define DFLTCC_FACILITY 151 | |
| 20 | + | |
| 21 | +/* | |
| 22 | + * Parameter Block for Query Available Functions. | |
| 23 | + */ | |
| 24 | +struct dfltcc_qaf_param { | |
| 25 | + char fns[16]; | |
| 26 | + char reserved1[8]; | |
| 27 | + char fmts[2]; | |
| 28 | + char reserved2[6]; | |
| 29 | +}; | |
| 30 | + | |
| 31 | +static_assert(sizeof(struct dfltcc_qaf_param) == 32); | |
| 32 | + | |
| 33 | +#define DFLTCC_FMT0 0 | |
| 34 | + | |
| 35 | +/* | |
| 36 | + * Parameter Block for Generate Dynamic-Huffman Table, Compress and Expand. | |
| 37 | + */ | |
| 38 | +struct dfltcc_param_v0 { | |
| 39 | + uint16_t pbvn; /* Parameter-Block-Version Number */ | |
| 40 | + uint8_t mvn; /* Model-Version Number */ | |
| 41 | + uint8_t ribm; /* Reserved for IBM use */ | |
| 42 | + unsigned reserved32 : 31; | |
| 43 | + unsigned cf : 1; /* Continuation Flag */ | |
| 44 | + uint8_t reserved64[8]; | |
| 45 | + unsigned nt : 1; /* New Task */ | |
| 46 | + unsigned reserved129 : 1; | |
| 47 | + unsigned cvt : 1; /* Check Value Type */ | |
| 48 | + unsigned reserved131 : 1; | |
| 49 | + unsigned htt : 1; /* Huffman-Table Type */ | |
| 50 | + unsigned bcf : 1; /* Block-Continuation Flag */ | |
| 51 | + unsigned bcc : 1; /* Block Closing Control */ | |
| 52 | + unsigned bhf : 1; /* Block Header Final */ | |
| 53 | + unsigned reserved136 : 1; | |
| 54 | + unsigned reserved137 : 1; | |
| 55 | + unsigned dhtgc : 1; /* DHT Generation Control */ | |
| 56 | + unsigned reserved139 : 5; | |
| 57 | + unsigned reserved144 : 5; | |
| 58 | + unsigned sbb : 3; /* Sub-Byte Boundary */ | |
| 59 | + uint8_t oesc; /* Operation-Ending-Supplemental Code */ | |
| 60 | + unsigned reserved160 : 12; | |
| 61 | + unsigned ifs : 4; /* Incomplete-Function Status */ | |
| 62 | + uint16_t ifl; /* Incomplete-Function Length */ | |
| 63 | + uint8_t reserved192[8]; | |
| 64 | + uint8_t reserved256[8]; | |
| 65 | + uint8_t reserved320[4]; | |
| 66 | + uint16_t hl; /* History Length */ | |
| 67 | + unsigned reserved368 : 1; | |
| 68 | + uint16_t ho : 15; /* History Offset */ | |
| 69 | + uint32_t cv; /* Check Value */ | |
| 70 | + unsigned eobs : 15; /* End-of-block Symbol */ | |
| 71 | + unsigned reserved431: 1; | |
| 72 | + uint8_t eobl : 4; /* End-of-block Length */ | |
| 73 | + unsigned reserved436 : 12; | |
| 74 | + unsigned reserved448 : 4; | |
| 75 | + uint16_t cdhtl : 12; /* Compressed-Dynamic-Huffman Table | |
| 76 | + Length */ | |
| 77 | + uint8_t reserved464[6]; | |
| 78 | + uint8_t cdht[288]; | |
| 79 | + uint8_t reserved[32]; | |
| 80 | + uint8_t csb[1152]; | |
| 81 | +}; | |
| 82 | + | |
| 83 | +static_assert(sizeof(struct dfltcc_param_v0) == 1536); | |
| 84 | + | |
| 85 | +#define CVT_CRC32 0 | |
| 86 | +#define CVT_ADLER32 1 | |
| 87 | +#define HTT_FIXED 0 | |
| 88 | +#define HTT_DYNAMIC 1 | |
| 89 | + | |
| 90 | +/* | |
| 91 | + * Extension of inflate_state and deflate_state for DFLTCC. | |
| 92 | + */ | |
| 93 | +struct dfltcc_state { | |
| 94 | + struct dfltcc_param_v0 param; /* Parameter block */ | |
| 95 | + struct dfltcc_qaf_param af; /* Available functions */ | |
| 96 | + uLong level_mask; /* Levels on which to use DFLTCC */ | |
| 97 | + uLong block_size; /* New block each X bytes */ | |
| 98 | + uLong block_threshold; /* New block after total_in > X */ | |
| 99 | + uLong dht_threshold; /* New block only if avail_in >= X */ | |
| 100 | + char msg[64]; /* Buffer for strm->msg */ | |
| 101 | +}; | |
| 102 | + | |
| 103 | +/* Resides right after inflate_state or deflate_state */ | |
| 104 | +#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((state) + 1)) | |
| 105 | + | |
| 106 | +/* External functions */ | |
| 107 | +int dfltcc_can_deflate(z_streamp strm); | |
| 108 | +int dfltcc_deflate(z_streamp strm, | |
| 109 | + int flush, | |
| 110 | + block_state *result); | |
| 111 | +void dfltcc_reset(z_streamp strm, uInt size); | |
| 112 | +int dfltcc_can_inflate(z_streamp strm); | |
| 113 | +typedef enum { | |
| 114 | + DFLTCC_INFLATE_CONTINUE, | |
| 115 | + DFLTCC_INFLATE_BREAK, | |
| 116 | + DFLTCC_INFLATE_SOFTWARE, | |
| 117 | +} dfltcc_inflate_action; | |
| 118 | +dfltcc_inflate_action dfltcc_inflate(z_streamp strm, | |
| 119 | + int flush, int *ret); | |
| 120 | +static inline int is_dfltcc_enabled(void) | |
| 121 | +{ | |
| 122 | +return (zlib_dfltcc_support != ZLIB_DFLTCC_DISABLED && | |
| 123 | + test_facility(DFLTCC_FACILITY)); | |
| 124 | +} | |
| 125 | + | |
| 126 | +#define DEFLATE_RESET_HOOK(strm) \ | |
| 127 | + dfltcc_reset((strm), sizeof(deflate_state)) | |
| 128 | + | |
| 129 | +#define DEFLATE_HOOK dfltcc_deflate | |
| 130 | + | |
| 131 | +#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm))) | |
| 132 | + | |
| 133 | +#define DEFLATE_DFLTCC_ENABLED() is_dfltcc_enabled() | |
| 134 | + | |
| 135 | +#define INFLATE_RESET_HOOK(strm) \ | |
| 136 | + dfltcc_reset((strm), sizeof(struct inflate_state)) | |
| 137 | + | |
| 138 | +#define INFLATE_TYPEDO_HOOK(strm, flush) \ | |
| 139 | + if (dfltcc_can_inflate((strm))) { \ | |
| 140 | + dfltcc_inflate_action action; \ | |
| 141 | +\ | |
| 142 | + RESTORE(); \ | |
| 143 | + action = dfltcc_inflate((strm), (flush), &ret); \ | |
| 144 | + LOAD(); \ | |
| 145 | + if (action == DFLTCC_INFLATE_CONTINUE) \ | |
| 146 | + break; \ | |
| 147 | + else if (action == DFLTCC_INFLATE_BREAK) \ | |
| 148 | + goto inf_leave; \ | |
| 149 | + } | |
| 150 | + | |
| 151 | +#define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm))) | |
| 152 | + | |
| 153 | +#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm))) | |
| 154 | + | |
| 155 | +#endif /* DFLTCC_H */ | |
| @@ -0,0 +1,279 @@ | ||
| 1 | +// SPDX-License-Identifier: Zlib | |
| 2 | + | |
| 3 | +#include "../zlib_deflate/defutil.h" | |
| 4 | +#include "dfltcc_util.h" | |
| 5 | +#include "dfltcc.h" | |
| 6 | +#include <asm/setup.h> | |
| 7 | +#include <linux/zutil.h> | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * Compress. | |
| 11 | + */ | |
| 12 | +int dfltcc_can_deflate( | |
| 13 | + z_streamp strm | |
| 14 | +) | |
| 15 | +{ | |
| 16 | + deflate_state *state = (deflate_state *)strm->state; | |
| 17 | + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); | |
| 18 | + | |
| 19 | + /* Check for kernel dfltcc command line parameter */ | |
| 20 | + if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED || | |
| 21 | + zlib_dfltcc_support == ZLIB_DFLTCC_INFLATE_ONLY) | |
| 22 | + return 0; | |
| 23 | + | |
| 24 | + /* Unsupported compression settings */ | |
| 25 | + if (!dfltcc_are_params_ok(state->level, state->w_bits, state->strategy, | |
| 26 | + dfltcc_state->level_mask)) | |
| 27 | + return 0; | |
| 28 | + | |
| 29 | + /* Unsupported hardware */ | |
| 30 | + if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) || | |
| 31 | + !is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) || | |
| 32 | + !is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0)) | |
| 33 | + return 0; | |
| 34 | + | |
| 35 | + return 1; | |
| 36 | +} | |
| 37 | + | |
| 38 | +static void dfltcc_gdht( | |
| 39 | + z_streamp strm | |
| 40 | +) | |
| 41 | +{ | |
| 42 | + deflate_state *state = (deflate_state *)strm->state; | |
| 43 | + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; | |
| 44 | + size_t avail_in = avail_in = strm->avail_in; | |
| 45 | + | |
| 46 | + dfltcc(DFLTCC_GDHT, | |
| 47 | + param, NULL, NULL, | |
| 48 | + &strm->next_in, &avail_in, NULL); | |
| 49 | +} | |
| 50 | + | |
| 51 | +static dfltcc_cc dfltcc_cmpr( | |
| 52 | + z_streamp strm | |
| 53 | +) | |
| 54 | +{ | |
| 55 | + deflate_state *state = (deflate_state *)strm->state; | |
| 56 | + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; | |
| 57 | + size_t avail_in = strm->avail_in; | |
| 58 | + size_t avail_out = strm->avail_out; | |
| 59 | + dfltcc_cc cc; | |
| 60 | + | |
| 61 | + cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR, | |
| 62 | + param, &strm->next_out, &avail_out, | |
| 63 | + &strm->next_in, &avail_in, state->window); | |
| 64 | + strm->total_in += (strm->avail_in - avail_in); | |
| 65 | + strm->total_out += (strm->avail_out - avail_out); | |
| 66 | + strm->avail_in = avail_in; | |
| 67 | + strm->avail_out = avail_out; | |
| 68 | + return cc; | |
| 69 | +} | |
| 70 | + | |
| 71 | +static void send_eobs( | |
| 72 | + z_streamp strm, | |
| 73 | + const struct dfltcc_param_v0 *param | |
| 74 | +) | |
| 75 | +{ | |
| 76 | + deflate_state *state = (deflate_state *)strm->state; | |
| 77 | + | |
| 78 | + zlib_tr_send_bits( | |
| 79 | + state, | |
| 80 | + bi_reverse(param->eobs >> (15 - param->eobl), param->eobl), | |
| 81 | + param->eobl); | |
| 82 | + flush_pending(strm); | |
| 83 | + if (state->pending != 0) { | |
| 84 | + /* The remaining data is located in pending_out[0:pending]. If someone | |
| 85 | + * calls put_byte() - this might happen in deflate() - the byte will be | |
| 86 | + * placed into pending_buf[pending], which is incorrect. Move the | |
| 87 | + * remaining data to the beginning of pending_buf so that put_byte() is | |
| 88 | + * usable again. | |
| 89 | + */ | |
| 90 | + memmove(state->pending_buf, state->pending_out, state->pending); | |
| 91 | + state->pending_out = state->pending_buf; | |
| 92 | + } | |
| 93 | +#ifdef ZLIB_DEBUG | |
| 94 | + state->compressed_len += param->eobl; | |
| 95 | +#endif | |
| 96 | +} | |
| 97 | + | |
| 98 | +int dfltcc_deflate( | |
| 99 | + z_streamp strm, | |
| 100 | + int flush, | |
| 101 | + block_state *result | |
| 102 | +) | |
| 103 | +{ | |
| 104 | + deflate_state *state = (deflate_state *)strm->state; | |
| 105 | + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); | |
| 106 | + struct dfltcc_param_v0 *param = &dfltcc_state->param; | |
| 107 | + uInt masked_avail_in; | |
| 108 | + dfltcc_cc cc; | |
| 109 | + int need_empty_block; | |
| 110 | + int soft_bcc; | |
| 111 | + int no_flush; | |
| 112 | + | |
| 113 | + if (!dfltcc_can_deflate(strm)) | |
| 114 | + return 0; | |
| 115 | + | |
| 116 | +again: | |
| 117 | + masked_avail_in = 0; | |
| 118 | + soft_bcc = 0; | |
| 119 | + no_flush = flush == Z_NO_FLUSH; | |
| 120 | + | |
| 121 | + /* Trailing empty block. Switch to software, except when Continuation Flag | |
| 122 | + * is set, which means that DFLTCC has buffered some output in the | |
| 123 | + * parameter block and needs to be called again in order to flush it. | |
| 124 | + */ | |
| 125 | + if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) { | |
| 126 | + if (param->bcf) { | |
| 127 | + /* A block is still open, and the hardware does not support closing | |
| 128 | + * blocks without adding data. Thus, close it manually. | |
| 129 | + */ | |
| 130 | + send_eobs(strm, param); | |
| 131 | + param->bcf = 0; | |
| 132 | + } | |
| 133 | + return 0; | |
| 134 | + } | |
| 135 | + | |
| 136 | + if (strm->avail_in == 0 && !param->cf) { | |
| 137 | + *result = need_more; | |
| 138 | + return 1; | |
| 139 | + } | |
| 140 | + | |
| 141 | + /* There is an open non-BFINAL block, we are not going to close it just | |
| 142 | + * yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see | |
| 143 | + * more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new | |
| 144 | + * DHT in order to adapt to a possibly changed input data distribution. | |
| 145 | + */ | |
| 146 | + if (param->bcf && no_flush && | |
| 147 | + strm->total_in > dfltcc_state->block_threshold && | |
| 148 | + strm->avail_in >= dfltcc_state->dht_threshold) { | |
| 149 | + if (param->cf) { | |
| 150 | + /* We need to flush the DFLTCC buffer before writing the | |
| 151 | + * End-of-block Symbol. Mask the input data and proceed as usual. | |
| 152 | + */ | |
| 153 | + masked_avail_in += strm->avail_in; | |
| 154 | + strm->avail_in = 0; | |
| 155 | + no_flush = 0; | |
| 156 | + } else { | |
| 157 | + /* DFLTCC buffer is empty, so we can manually write the | |
| 158 | + * End-of-block Symbol right away. | |
| 159 | + */ | |
| 160 | + send_eobs(strm, param); | |
| 161 | + param->bcf = 0; | |
| 162 | + dfltcc_state->block_threshold = | |
| 163 | + strm->total_in + dfltcc_state->block_size; | |
| 164 | + if (strm->avail_out == 0) { | |
| 165 | + *result = need_more; | |
| 166 | + return 1; | |
| 167 | + } | |
| 168 | + } | |
| 169 | + } | |
| 170 | + | |
| 171 | + /* The caller gave us too much data. Pass only one block worth of | |
| 172 | + * uncompressed data to DFLTCC and mask the rest, so that on the next | |
| 173 | + * iteration we start a new block. | |
| 174 | + */ | |
| 175 | + if (no_flush && strm->avail_in > dfltcc_state->block_size) { | |
| 176 | + masked_avail_in += (strm->avail_in - dfltcc_state->block_size); | |
| 177 | + strm->avail_in = dfltcc_state->block_size; | |
| 178 | + } | |
| 179 | + | |
| 180 | + /* When we have an open non-BFINAL deflate block and caller indicates that | |
| 181 | + * the stream is ending, we need to close an open deflate block and open a | |
| 182 | + * BFINAL one. | |
| 183 | + */ | |
| 184 | + need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf; | |
| 185 | + | |
| 186 | + /* Translate stream to parameter block */ | |
| 187 | + param->cvt = CVT_ADLER32; | |
| 188 | + if (!no_flush) | |
| 189 | + /* We need to close a block. Always do this in software - when there is | |
| 190 | + * no input data, the hardware will not nohor BCC. */ | |
| 191 | + soft_bcc = 1; | |
| 192 | + if (flush == Z_FINISH && !param->bcf) | |
| 193 | + /* We are about to open a BFINAL block, set Block Header Final bit | |
| 194 | + * until the stream ends. | |
| 195 | + */ | |
| 196 | + param->bhf = 1; | |
| 197 | + /* DFLTCC-CMPR will write to next_out, so make sure that buffers with | |
| 198 | + * higher precedence are empty. | |
| 199 | + */ | |
| 200 | + Assert(state->pending == 0, "There must be no pending bytes"); | |
| 201 | + Assert(state->bi_valid < 8, "There must be less than 8 pending bits"); | |
| 202 | + param->sbb = (unsigned int)state->bi_valid; | |
| 203 | + if (param->sbb > 0) | |
| 204 | + *strm->next_out = (Byte)state->bi_buf; | |
| 205 | + if (param->hl) | |
| 206 | + param->nt = 0; /* Honor history */ | |
| 207 | + param->cv = strm->adler; | |
| 208 | + | |
| 209 | + /* When opening a block, choose a Huffman-Table Type */ | |
| 210 | + if (!param->bcf) { | |
| 211 | + if (strm->total_in == 0 && dfltcc_state->block_threshold > 0) { | |
| 212 | + param->htt = HTT_FIXED; | |
| 213 | + } | |
| 214 | + else { | |
| 215 | + param->htt = HTT_DYNAMIC; | |
| 216 | + dfltcc_gdht(strm); | |
| 217 | + } | |
| 218 | + } | |
| 219 | + | |
| 220 | + /* Deflate */ | |
| 221 | + do { | |
| 222 | + cc = dfltcc_cmpr(strm); | |
| 223 | + if (strm->avail_in < 4096 && masked_avail_in > 0) | |
| 224 | + /* We are about to call DFLTCC with a small input buffer, which is | |
| 225 | + * inefficient. Since there is masked data, there will be at least | |
| 226 | + * one more DFLTCC call, so skip the current one and make the next | |
| 227 | + * one handle more data. | |
| 228 | + */ | |
| 229 | + break; | |
| 230 | + } while (cc == DFLTCC_CC_AGAIN); | |
| 231 | + | |
| 232 | + /* Translate parameter block to stream */ | |
| 233 | + strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); | |
| 234 | + state->bi_valid = param->sbb; | |
| 235 | + if (state->bi_valid == 0) | |
| 236 | + state->bi_buf = 0; /* Avoid accessing next_out */ | |
| 237 | + else | |
| 238 | + state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1); | |
| 239 | + strm->adler = param->cv; | |
| 240 | + | |
| 241 | + /* Unmask the input data */ | |
| 242 | + strm->avail_in += masked_avail_in; | |
| 243 | + masked_avail_in = 0; | |
| 244 | + | |
| 245 | + /* If we encounter an error, it means there is a bug in DFLTCC call */ | |
| 246 | + Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG"); | |
| 247 | + | |
| 248 | + /* Update Block-Continuation Flag. It will be used to check whether to call | |
| 249 | + * GDHT the next time. | |
| 250 | + */ | |
| 251 | + if (cc == DFLTCC_CC_OK) { | |
| 252 | + if (soft_bcc) { | |
| 253 | + send_eobs(strm, param); | |
| 254 | + param->bcf = 0; | |
| 255 | + dfltcc_state->block_threshold = | |
| 256 | + strm->total_in + dfltcc_state->block_size; | |
| 257 | + } else | |
| 258 | + param->bcf = 1; | |
| 259 | + if (flush == Z_FINISH) { | |
| 260 | + if (need_empty_block) | |
| 261 | + /* Make the current deflate() call also close the stream */ | |
| 262 | + return 0; | |
| 263 | + else { | |
| 264 | + bi_windup(state); | |
| 265 | + *result = finish_done; | |
| 266 | + } | |
| 267 | + } else { | |
| 268 | + if (flush == Z_FULL_FLUSH) | |
| 269 | + param->hl = 0; /* Clear history */ | |
| 270 | + *result = flush == Z_NO_FLUSH ? need_more : block_done; | |
| 271 | + } | |
| 272 | + } else { | |
| 273 | + param->bcf = 1; | |
| 274 | + *result = need_more; | |
| 275 | + } | |
| 276 | + if (strm->avail_in != 0 && strm->avail_out != 0) | |
| 277 | + goto again; /* deflate() must use all input or all output */ | |
| 278 | + return 1; | |
| 279 | +} | |
| @@ -0,0 +1,149 @@ | ||
| 1 | +// SPDX-License-Identifier: Zlib | |
| 2 | + | |
| 3 | +#include "../zlib_inflate/inflate.h" | |
| 4 | +#include "dfltcc_util.h" | |
| 5 | +#include "dfltcc.h" | |
| 6 | +#include <asm/setup.h> | |
| 7 | +#include <linux/zutil.h> | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * Expand. | |
| 11 | + */ | |
| 12 | +int dfltcc_can_inflate( | |
| 13 | + z_streamp strm | |
| 14 | +) | |
| 15 | +{ | |
| 16 | + struct inflate_state *state = (struct inflate_state *)strm->state; | |
| 17 | + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); | |
| 18 | + | |
| 19 | + /* Check for kernel dfltcc command line parameter */ | |
| 20 | + if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED || | |
| 21 | + zlib_dfltcc_support == ZLIB_DFLTCC_DEFLATE_ONLY) | |
| 22 | + return 0; | |
| 23 | + | |
| 24 | + /* Unsupported compression settings */ | |
| 25 | + if (state->wbits != HB_BITS) | |
| 26 | + return 0; | |
| 27 | + | |
| 28 | + /* Unsupported hardware */ | |
| 29 | + return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) && | |
| 30 | + is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0); | |
| 31 | +} | |
| 32 | + | |
| 33 | +static int dfltcc_was_inflate_used( | |
| 34 | + z_streamp strm | |
| 35 | +) | |
| 36 | +{ | |
| 37 | + struct inflate_state *state = (struct inflate_state *)strm->state; | |
| 38 | + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; | |
| 39 | + | |
| 40 | + return !param->nt; | |
| 41 | +} | |
| 42 | + | |
| 43 | +static int dfltcc_inflate_disable( | |
| 44 | + z_streamp strm | |
| 45 | +) | |
| 46 | +{ | |
| 47 | + struct inflate_state *state = (struct inflate_state *)strm->state; | |
| 48 | + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); | |
| 49 | + | |
| 50 | + if (!dfltcc_can_inflate(strm)) | |
| 51 | + return 0; | |
| 52 | + if (dfltcc_was_inflate_used(strm)) | |
| 53 | + /* DFLTCC has already decompressed some data. Since there is not | |
| 54 | + * enough information to resume decompression in software, the call | |
| 55 | + * must fail. | |
| 56 | + */ | |
| 57 | + return 1; | |
| 58 | + /* DFLTCC was not used yet - decompress in software */ | |
| 59 | + memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); | |
| 60 | + return 0; | |
| 61 | +} | |
| 62 | + | |
| 63 | +static dfltcc_cc dfltcc_xpnd( | |
| 64 | + z_streamp strm | |
| 65 | +) | |
| 66 | +{ | |
| 67 | + struct inflate_state *state = (struct inflate_state *)strm->state; | |
| 68 | + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; | |
| 69 | + size_t avail_in = strm->avail_in; | |
| 70 | + size_t avail_out = strm->avail_out; | |
| 71 | + dfltcc_cc cc; | |
| 72 | + | |
| 73 | + cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR, | |
| 74 | + param, &strm->next_out, &avail_out, | |
| 75 | + &strm->next_in, &avail_in, state->window); | |
| 76 | + strm->avail_in = avail_in; | |
| 77 | + strm->avail_out = avail_out; | |
| 78 | + return cc; | |
| 79 | +} | |
| 80 | + | |
| 81 | +dfltcc_inflate_action dfltcc_inflate( | |
| 82 | + z_streamp strm, | |
| 83 | + int flush, | |
| 84 | + int *ret | |
| 85 | +) | |
| 86 | +{ | |
| 87 | + struct inflate_state *state = (struct inflate_state *)strm->state; | |
| 88 | + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); | |
| 89 | + struct dfltcc_param_v0 *param = &dfltcc_state->param; | |
| 90 | + dfltcc_cc cc; | |
| 91 | + | |
| 92 | + if (flush == Z_BLOCK) { | |
| 93 | + /* DFLTCC does not support stopping on block boundaries */ | |
| 94 | + if (dfltcc_inflate_disable(strm)) { | |
| 95 | + *ret = Z_STREAM_ERROR; | |
| 96 | + return DFLTCC_INFLATE_BREAK; | |
| 97 | + } else | |
| 98 | + return DFLTCC_INFLATE_SOFTWARE; | |
| 99 | + } | |
| 100 | + | |
| 101 | + if (state->last) { | |
| 102 | + if (state->bits != 0) { | |
| 103 | + strm->next_in++; | |
| 104 | + strm->avail_in--; | |
| 105 | + state->bits = 0; | |
| 106 | + } | |
| 107 | + state->mode = CHECK; | |
| 108 | + return DFLTCC_INFLATE_CONTINUE; | |
| 109 | + } | |
| 110 | + | |
| 111 | + if (strm->avail_in == 0 && !param->cf) | |
| 112 | + return DFLTCC_INFLATE_BREAK; | |
| 113 | + | |
| 114 | + if (!state->window || state->wsize == 0) { | |
| 115 | + state->mode = MEM; | |
| 116 | + return DFLTCC_INFLATE_CONTINUE; | |
| 117 | + } | |
| 118 | + | |
| 119 | + /* Translate stream to parameter block */ | |
| 120 | + param->cvt = CVT_ADLER32; | |
| 121 | + param->sbb = state->bits; | |
| 122 | + param->hl = state->whave; /* Software and hardware history formats match */ | |
| 123 | + param->ho = (state->write - state->whave) & ((1 << HB_BITS) - 1); | |
| 124 | + if (param->hl) | |
| 125 | + param->nt = 0; /* Honor history for the first block */ | |
| 126 | + param->cv = state->flags ? REVERSE(state->check) : state->check; | |
| 127 | + | |
| 128 | + /* Inflate */ | |
| 129 | + do { | |
| 130 | + cc = dfltcc_xpnd(strm); | |
| 131 | + } while (cc == DFLTCC_CC_AGAIN); | |
| 132 | + | |
| 133 | + /* Translate parameter block to stream */ | |
| 134 | + strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); | |
| 135 | + state->last = cc == DFLTCC_CC_OK; | |
| 136 | + state->bits = param->sbb; | |
| 137 | + state->whave = param->hl; | |
| 138 | + state->write = (param->ho + param->hl) & ((1 << HB_BITS) - 1); | |
| 139 | + state->check = state->flags ? REVERSE(param->cv) : param->cv; | |
| 140 | + if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) { | |
| 141 | + /* Report an error if stream is corrupted */ | |
| 142 | + state->mode = BAD; | |
| 143 | + return DFLTCC_INFLATE_CONTINUE; | |
| 144 | + } | |
| 145 | + state->mode = TYPEDO; | |
| 146 | + /* Break if operands are exhausted, otherwise continue looping */ | |
| 147 | + return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ? | |
| 148 | + DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE; | |
| 149 | +} | |
| @@ -0,0 +1,17 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +/* | |
| 3 | + * linux/lib/zlib_dfltcc/dfltcc_syms.c | |
| 4 | + * | |
| 5 | + * Exported symbols for the s390 zlib dfltcc support. | |
| 6 | + * | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#include <linux/init.h> | |
| 10 | +#include <linux/module.h> | |
| 11 | +#include <linux/zlib.h> | |
| 12 | +#include "dfltcc.h" | |
| 13 | + | |
| 14 | +EXPORT_SYMBOL(dfltcc_can_deflate); | |
| 15 | +EXPORT_SYMBOL(dfltcc_deflate); | |
| 16 | +EXPORT_SYMBOL(dfltcc_reset); | |
| 17 | +MODULE_LICENSE("GPL"); | |
| @@ -0,0 +1,103 @@ | ||
| 1 | +// SPDX-License-Identifier: Zlib | |
| 2 | +#ifndef DFLTCC_UTIL_H | |
| 3 | +#define DFLTCC_UTIL_H | |
| 4 | + | |
| 5 | +#include <linux/zutil.h> | |
| 6 | + | |
| 7 | +/* | |
| 8 | + * C wrapper for the DEFLATE CONVERSION CALL instruction. | |
| 9 | + */ | |
| 10 | +typedef enum { | |
| 11 | + DFLTCC_CC_OK = 0, | |
| 12 | + DFLTCC_CC_OP1_TOO_SHORT = 1, | |
| 13 | + DFLTCC_CC_OP2_TOO_SHORT = 2, | |
| 14 | + DFLTCC_CC_OP2_CORRUPT = 2, | |
| 15 | + DFLTCC_CC_AGAIN = 3, | |
| 16 | +} dfltcc_cc; | |
| 17 | + | |
| 18 | +#define DFLTCC_QAF 0 | |
| 19 | +#define DFLTCC_GDHT 1 | |
| 20 | +#define DFLTCC_CMPR 2 | |
| 21 | +#define DFLTCC_XPND 4 | |
| 22 | +#define HBT_CIRCULAR (1 << 7) | |
| 23 | +#define HB_BITS 15 | |
| 24 | +#define HB_SIZE (1 << HB_BITS) | |
| 25 | + | |
| 26 | +static inline dfltcc_cc dfltcc( | |
| 27 | + int fn, | |
| 28 | + void *param, | |
| 29 | + Byte **op1, | |
| 30 | + size_t *len1, | |
| 31 | + const Byte **op2, | |
| 32 | + size_t *len2, | |
| 33 | + void *hist | |
| 34 | +) | |
| 35 | +{ | |
| 36 | + Byte *t2 = op1 ? *op1 : NULL; | |
| 37 | + size_t t3 = len1 ? *len1 : 0; | |
| 38 | + const Byte *t4 = op2 ? *op2 : NULL; | |
| 39 | + size_t t5 = len2 ? *len2 : 0; | |
| 40 | + register int r0 __asm__("r0") = fn; | |
| 41 | + register void *r1 __asm__("r1") = param; | |
| 42 | + register Byte *r2 __asm__("r2") = t2; | |
| 43 | + register size_t r3 __asm__("r3") = t3; | |
| 44 | + register const Byte *r4 __asm__("r4") = t4; | |
| 45 | + register size_t r5 __asm__("r5") = t5; | |
| 46 | + int cc; | |
| 47 | + | |
| 48 | + __asm__ volatile( | |
| 49 | + ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n" | |
| 50 | + "ipm %[cc]\n" | |
| 51 | + : [r2] "+r" (r2) | |
| 52 | + , [r3] "+r" (r3) | |
| 53 | + , [r4] "+r" (r4) | |
| 54 | + , [r5] "+r" (r5) | |
| 55 | + , [cc] "=r" (cc) | |
| 56 | + : [r0] "r" (r0) | |
| 57 | + , [r1] "r" (r1) | |
| 58 | + , [hist] "r" (hist) | |
| 59 | + : "cc", "memory"); | |
| 60 | + t2 = r2; t3 = r3; t4 = r4; t5 = r5; | |
| 61 | + | |
| 62 | + if (op1) | |
| 63 | + *op1 = t2; | |
| 64 | + if (len1) | |
| 65 | + *len1 = t3; | |
| 66 | + if (op2) | |
| 67 | + *op2 = t4; | |
| 68 | + if (len2) | |
| 69 | + *len2 = t5; | |
| 70 | + return (cc >> 28) & 3; | |
| 71 | +} | |
| 72 | + | |
| 73 | +static inline int is_bit_set( | |
| 74 | + const char *bits, | |
| 75 | + int n | |
| 76 | +) | |
| 77 | +{ | |
| 78 | + return bits[n / 8] & (1 << (7 - (n % 8))); | |
| 79 | +} | |
| 80 | + | |
| 81 | +static inline void turn_bit_off( | |
| 82 | + char *bits, | |
| 83 | + int n | |
| 84 | +) | |
| 85 | +{ | |
| 86 | + bits[n / 8] &= ~(1 << (7 - (n % 8))); | |
| 87 | +} | |
| 88 | + | |
| 89 | +static inline int dfltcc_are_params_ok( | |
| 90 | + int level, | |
| 91 | + uInt window_bits, | |
| 92 | + int strategy, | |
| 93 | + uLong level_mask | |
| 94 | +) | |
| 95 | +{ | |
| 96 | + return (level_mask & (1 << level)) != 0 && | |
| 97 | + (window_bits == HB_BITS) && | |
| 98 | + (strategy == Z_DEFAULT_STRATEGY); | |
| 99 | +} | |
| 100 | + | |
| 101 | +char *oesc_msg(char *buf, int oesc); | |
| 102 | + | |
| 103 | +#endif /* DFLTCC_UTIL_H */ | |
| @@ -15,6 +15,16 @@ · 14 unmodified lines | ||
| 15 | 15 | #include "inffast.h" |
| 16 | 16 | #include "infutil.h" |
| 17 | 17 | |
| 18 | +/* architecture-specific bits */ | |
| 19 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 20 | +# include "../zlib_dfltcc/dfltcc.h" | |
| 21 | +#else | |
| 22 | +#define INFLATE_RESET_HOOK(strm) do {} while (0) | |
| 23 | +#define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0) | |
| 24 | +#define INFLATE_NEED_UPDATEWINDOW(strm) 1 | |
| 25 | +#define INFLATE_NEED_CHECKSUM(strm) 1 | |
| 26 | +#endif | |
| 27 | + | |
| 18 | 28 | int zlib_inflate_workspacesize(void) |
| 19 | 29 | { |
| 20 | 30 | return sizeof(struct inflate_workspace); |
| @@ -42,6 +52,7 @@ int zlib_inflateReset(z_streamp strm) · 21 unmodified lines | ||
| 42 | 52 | state->write = 0; |
| 43 | 53 | state->whave = 0; |
| 44 | 54 | |
| 55 | + INFLATE_RESET_HOOK(strm); | |
| 45 | 56 | return Z_OK; |
| 46 | 57 | } |
| 47 | 58 | |
| @@ -66,7 +77,15 @@ int zlib_inflateInit2(z_streamp strm, int windowBits) · 18 unmodified lines | ||
| 66 | 77 | return Z_STREAM_ERROR; |
| 67 | 78 | } |
| 68 | 79 | state->wbits = (unsigned)windowBits; |
| 80 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 81 | + /* | |
| 82 | + * DFLTCC requires the window to be page aligned. | |
| 83 | + * Thus, we overallocate and take the aligned portion of the buffer. | |
| 84 | + */ | |
| 85 | + state->window = PTR_ALIGN(&WS(strm)->working_window[0], PAGE_SIZE); | |
| 86 | +#else | |
| 69 | 87 | state->window = &WS(strm)->working_window[0]; |
| 88 | +#endif | |
| 70 | 89 | |
| 71 | 90 | return zlib_inflateReset(strm); |
| 72 | 91 | } |
| @@ -227,11 +246,6 @@ static int zlib_inflateSyncPacket(z_streamp strm) · 154 unmodified lines | ||
| 227 | 246 | bits -= bits & 7; \ |
| 228 | 247 | } while (0) |
| 229 | 248 | |
| 230 | −/* Reverse the bytes in a 32-bit value */ | |
| 231 | −#define REVERSE(q) \ | |
| 232 | − ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ | |
| 233 | − (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) | |
| 234 | − | |
| 235 | 249 | /* |
| 236 | 250 | inflate() uses a state machine to process as much input data and generate as |
| 237 | 251 | much output data as possible before returning. The state machine is |
| @@ -395,6 +409,7 @@ int zlib_inflate(z_streamp strm, int flush) · 157 unmodified lines | ||
| 395 | 409 | if (flush == Z_BLOCK) goto inf_leave; |
| 396 | 410 | /* fall through */ |
| 397 | 411 | case TYPEDO: |
| 412 | + INFLATE_TYPEDO_HOOK(strm, flush); | |
| 398 | 413 | if (state->last) { |
| 399 | 414 | BYTEBITS(); |
| 400 | 415 | state->mode = CHECK; |
| @@ -692,7 +707,7 @@ int zlib_inflate(z_streamp strm, int flush) · 291 unmodified lines | ||
| 692 | 707 | out -= left; |
| 693 | 708 | strm->total_out += out; |
| 694 | 709 | state->total += out; |
| 695 | − if (out) | |
| 710 | + if (INFLATE_NEED_CHECKSUM(strm) && out) | |
| 696 | 711 | strm->adler = state->check = |
| 697 | 712 | UPDATE(state->check, put - out, out); |
| 698 | 713 | out = left; |
| @@ -726,7 +741,8 @@ int zlib_inflate(z_streamp strm, int flush) · 27 unmodified lines | ||
| 726 | 741 | */ |
| 727 | 742 | inf_leave: |
| 728 | 743 | RESTORE(); |
| 729 | − if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) | |
| 744 | + if (INFLATE_NEED_UPDATEWINDOW(strm) && | |
| 745 | + (state->wsize || (state->mode < CHECK && out != strm->avail_out))) | |
| 730 | 746 | zlib_updatewindow(strm, out); |
| 731 | 747 | |
| 732 | 748 | in -= strm->avail_in; |
| @@ -734,7 +750,7 @@ int zlib_inflate(z_streamp strm, int flush) · 1 unmodified line | ||
| 734 | 750 | strm->total_in += in; |
| 735 | 751 | strm->total_out += out; |
| 736 | 752 | state->total += out; |
| 737 | − if (state->wrap && out) | |
| 753 | + if (INFLATE_NEED_CHECKSUM(strm) && state->wrap && out) | |
| 738 | 754 | strm->adler = state->check = |
| 739 | 755 | UPDATE(state->check, strm->next_out - out, out); |
| 740 | 756 | |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | ||
| 11 | 11 | subject to change. Applications should only use zlib.h. |
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | +#include "inftrees.h" | |
| 15 | + | |
| 14 | 16 | /* Possible inflate modes between inflate() calls */ |
| 15 | 17 | typedef enum { |
| 16 | 18 | HEAD, /* i: waiting for magic header */ |
| @@ -108,4 +110,10 @@ struct inflate_state { · 91 unmodified lines | ||
| 108 | 110 | unsigned short work[288]; /* work area for code table building */ |
| 109 | 111 | code codes[ENOUGH]; /* space for code tables */ |
| 110 | 112 | }; |
| 113 | + | |
| 114 | +/* Reverse the bytes in a 32-bit value */ | |
| 115 | +#define REVERSE(q) \ | |
| 116 | + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ | |
| 117 | + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) | |
| 118 | + | |
| 111 | 119 | #endif |
| @@ -12,14 +12,28 @@ · 11 unmodified lines | ||
| 12 | 12 | #define _INFUTIL_H |
| 13 | 13 | |
| 14 | 14 | #include <linux/zlib.h> |
| 15 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 16 | +#include "../zlib_dfltcc/dfltcc.h" | |
| 17 | +#include <asm/page.h> | |
| 18 | +#endif | |
| 15 | 19 | |
| 16 | 20 | /* memory allocation for inflation */ |
| 17 | 21 | |
| 18 | 22 | struct inflate_workspace { |
| 19 | 23 | struct inflate_state inflate_state; |
| 20 | − unsigned char working_window[1 << MAX_WBITS]; | |
| 24 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 25 | + struct dfltcc_state dfltcc_state; | |
| 26 | + unsigned char working_window[(1 << MAX_WBITS) + PAGE_SIZE]; | |
| 27 | +#else | |
| 28 | + unsigned char working_window[(1 << MAX_WBITS)]; | |
| 29 | +#endif | |
| 21 | 30 | }; |
| 22 | 31 | |
| 23 | −#define WS(z) ((struct inflate_workspace *)(z->workspace)) | |
| 32 | +#ifdef CONFIG_ZLIB_DFLTCC | |
| 33 | +/* dfltcc_state must be doubleword aligned for DFLTCC call */ | |
| 34 | +static_assert(offsetof(struct inflate_workspace, dfltcc_state) % 8 == 0); | |
| 35 | +#endif | |
| 36 | + | |
| 37 | +#define WS(strm) ((struct inflate_workspace *)(strm->workspace)) | |
| 24 | 38 | |
| 25 | 39 | #endif |
| @@ -20,6 +20,7 @@ KCOV_INSTRUMENT_kmemleak.o := n · 19 unmodified lines | ||
| 20 | 20 | KCOV_INSTRUMENT_memcontrol.o := n |
| 21 | 21 | KCOV_INSTRUMENT_mmzone.o := n |
| 22 | 22 | KCOV_INSTRUMENT_vmstat.o := n |
| 23 | +KCOV_INSTRUMENT_failslab.o := n | |
| 23 | 24 | |
| 24 | 25 | CFLAGS_init-mm.o += $(call cc-disable-warning, override-init) |
| 25 | 26 | CFLAGS_init-mm.o += $(call cc-disable-warning, initializer-overrides) |
| @@ -21,6 +21,7 @@ struct backing_dev_info noop_backing_dev_info = { · 20 unmodified lines | ||
| 21 | 21 | EXPORT_SYMBOL_GPL(noop_backing_dev_info); |
| 22 | 22 | |
| 23 | 23 | static struct class *bdi_class; |
| 24 | +const char *bdi_unknown_name = "(unknown)"; | |
| 24 | 25 | |
| 25 | 26 | /* |
| 26 | 27 | * bdi_lock protects bdi_tree and updates to bdi_list. bdi_list has RCU |
| @@ -46,7 +46,15 @@ void __dump_page(struct page *page, const char *reason) · 45 unmodified lines | ||
| 46 | 46 | { |
| 47 | 47 | struct address_space *mapping; |
| 48 | 48 | bool page_poisoned = PagePoisoned(page); |
| 49 | + /* | |
| 50 | + * Accessing the pageblock without the zone lock. It could change to | |
| 51 | + * "isolate" again in the meantime, but since we are just dumping the | |
| 52 | + * state for debugging, it should be fine to accept a bit of | |
| 53 | + * inaccuracy here due to racing. | |
| 54 | + */ | |
| 55 | + bool page_cma = is_migrate_cma_page(page); | |
| 49 | 56 | int mapcount; |
| 57 | + char *type = ""; | |
| 50 | 58 | |
| 51 | 59 | /* |
| 52 | 60 | * If struct page is poisoned don't access Page*() functions as that |
| @@ -78,9 +86,9 @@ void __dump_page(struct page *page, const char *reason) · 25 unmodified lines | ||
| 78 | 86 | page, page_ref_count(page), mapcount, |
| 79 | 87 | page->mapping, page_to_pgoff(page)); |
| 80 | 88 | if (PageKsm(page)) |
| 81 | − pr_warn("ksm flags: %#lx(%pGp)\n", page->flags, &page->flags); | |
| 89 | + type = "ksm "; | |
| 82 | 90 | else if (PageAnon(page)) |
| 83 | − pr_warn("anon flags: %#lx(%pGp)\n", page->flags, &page->flags); | |
| 91 | + type = "anon "; | |
| 84 | 92 | else if (mapping) { |
| 85 | 93 | if (mapping->host && mapping->host->i_dentry.first) { |
| 86 | 94 | struct dentry *dentry; |
| @@ -88,10 +96,12 @@ void __dump_page(struct page *page, const char *reason) · 1 unmodified line | ||
| 88 | 96 | pr_warn("%ps name:\"%pd\"\n", mapping->a_ops, dentry); |
| 89 | 97 | } else |
| 90 | 98 | pr_warn("%ps\n", mapping->a_ops); |
| 91 | − pr_warn("flags: %#lx(%pGp)\n", page->flags, &page->flags); | |
| 92 | 99 | } |
| 93 | 100 | BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS + 1); |
| 94 | 101 | |
| 102 | + pr_warn("%sflags: %#lx(%pGp)%s\n", type, page->flags, &page->flags, | |
| 103 | + page_cma ? " CMA" : ""); | |
| 104 | + | |
| 95 | 105 | hex_only: |
| 96 | 106 | print_hex_dump(KERN_WARNING, "raw: ", DUMP_PREFIX_NONE, 32, |
| 97 | 107 | sizeof(unsigned long), page, |
| @@ -121,8 +121,8 @@ __early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot) · 120 unmodified lines | ||
| 121 | 121 | } |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | − if (WARN(slot < 0, "%s(%08llx, %08lx) not found slot\n", | |
| 125 | − __func__, (u64)phys_addr, size)) | |
| 124 | + if (WARN(slot < 0, "%s(%pa, %08lx) not found slot\n", | |
| 125 | + __func__, &phys_addr, size)) | |
| 126 | 126 | return NULL; |
| 127 | 127 | |
| 128 | 128 | /* Don't allow wraparound or zero size */ |
| @@ -158,8 +158,8 @@ __early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot) · 29 unmodified lines | ||
| 158 | 158 | --idx; |
| 159 | 159 | --nrpages; |
| 160 | 160 | } |
| 161 | − WARN(early_ioremap_debug, "%s(%08llx, %08lx) [%d] => %08lx + %08lx\n", | |
| 162 | − __func__, (u64)phys_addr, size, slot, offset, slot_virt[slot]); | |
| 161 | + WARN(early_ioremap_debug, "%s(%pa, %08lx) [%d] => %08lx + %08lx\n", | |
| 162 | + __func__, &phys_addr, size, slot, offset, slot_virt[slot]); | |
| 163 | 163 | |
| 164 | 164 | prev_map[slot] = (void __iomem *)(offset + slot_virt[slot]); |
| 165 | 165 | return prev_map[slot]; |
| @@ -632,33 +632,6 @@ static bool mapping_needs_writeback(struct address_space *mapping) · 631 unmodified lines | ||
| 632 | 632 | return mapping->nrpages; |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | −int filemap_write_and_wait(struct address_space *mapping) | |
| 636 | −{ | |
| 637 | − int err = 0; | |
| 638 | − | |
| 639 | − if (mapping_needs_writeback(mapping)) { | |
| 640 | − err = filemap_fdatawrite(mapping); | |
| 641 | − /* | |
| 642 | − * Even if the above returned error, the pages may be | |
| 643 | − * written partially (e.g. -ENOSPC), so we wait for it. | |
| 644 | − * But the -EIO is special case, it may indicate the worst | |
| 645 | − * thing (e.g. bug) happened, so we avoid waiting for it. | |
| 646 | − */ | |
| 647 | − if (err != -EIO) { | |
| 648 | − int err2 = filemap_fdatawait(mapping); | |
| 649 | − if (!err) | |
| 650 | − err = err2; | |
| 651 | − } else { | |
| 652 | − /* Clear any previously stored errors */ | |
| 653 | − filemap_check_errors(mapping); | |
| 654 | − } | |
| 655 | − } else { | |
| 656 | − err = filemap_check_errors(mapping); | |
| 657 | − } | |
| 658 | − return err; | |
| 659 | −} | |
| 660 | −EXPORT_SYMBOL(filemap_write_and_wait); | |
| 661 | − | |
| 662 | 635 | /** |
| 663 | 636 | * filemap_write_and_wait_range - write out & wait on a file range |
| 664 | 637 | * @mapping: the address_space for the pages |
| @@ -680,7 +653,12 @@ int filemap_write_and_wait_range(struct address_space *mapping, · 15 unmodified lines | ||
| 680 | 653 | if (mapping_needs_writeback(mapping)) { |
| 681 | 654 | err = __filemap_fdatawrite_range(mapping, lstart, lend, |
| 682 | 655 | WB_SYNC_ALL); |
| 683 | − /* See comment of filemap_write_and_wait() */ | |
| 656 | + /* | |
| 657 | + * Even if the above returned error, the pages may be | |
| 658 | + * written partially (e.g. -ENOSPC), so we wait for it. | |
| 659 | + * But the -EIO is special case, it may indicate the worst | |
| 660 | + * thing (e.g. bug) happened, so we avoid waiting for it. | |
| 661 | + */ | |
| 684 | 662 | if (err != -EIO) { |
| 685 | 663 | int err2 = filemap_fdatawait_range(mapping, |
| 686 | 664 | lstart, lend); |
| @@ -29,8 +29,23 @@ struct follow_page_context { · 28 unmodified lines | ||
| 29 | 29 | unsigned int page_mask; |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | +/* | |
| 33 | + * Return the compound head page with ref appropriately incremented, | |
| 34 | + * or NULL if that failed. | |
| 35 | + */ | |
| 36 | +static inline struct page *try_get_compound_head(struct page *page, int refs) | |
| 37 | +{ | |
| 38 | + struct page *head = compound_head(page); | |
| 39 | + | |
| 40 | + if (WARN_ON_ONCE(page_ref_count(head) < 0)) | |
| 41 | + return NULL; | |
| 42 | + if (unlikely(!page_cache_add_speculative(head, refs))) | |
| 43 | + return NULL; | |
| 44 | + return head; | |
| 45 | +} | |
| 46 | + | |
| 32 | 47 | /** |
| 33 | − * put_user_pages_dirty_lock() - release and optionally dirty gup-pinned pages | |
| 48 | + * unpin_user_pages_dirty_lock() - release and optionally dirty gup-pinned pages | |
| 34 | 49 | * @pages: array of pages to be maybe marked dirty, and definitely released. |
| 35 | 50 | * @npages: number of pages in the @pages array. |
| 36 | 51 | * @make_dirty: whether to mark the pages dirty |
| @@ -40,19 +55,19 @@ struct follow_page_context { · 3 unmodified lines | ||
| 40 | 55 | * |
| 41 | 56 | * For each page in the @pages array, make that page (or its head page, if a |
| 42 | 57 | * compound page) dirty, if @make_dirty is true, and if the page was previously |
| 43 | − * listed as clean. In any case, releases all pages using put_user_page(), | |
| 44 | − * possibly via put_user_pages(), for the non-dirty case. | |
| 58 | + * listed as clean. In any case, releases all pages using unpin_user_page(), | |
| 59 | + * possibly via unpin_user_pages(), for the non-dirty case. | |
| 45 | 60 | * |
| 46 | − * Please see the put_user_page() documentation for details. | |
| 61 | + * Please see the unpin_user_page() documentation for details. | |
| 47 | 62 | * |
| 48 | 63 | * set_page_dirty_lock() is used internally. If instead, set_page_dirty() is |
| 49 | 64 | * required, then the caller should a) verify that this is really correct, |
| 50 | 65 | * because _lock() is usually required, and b) hand code it: |
| 51 | − * set_page_dirty_lock(), put_user_page(). | |
| 66 | + * set_page_dirty_lock(), unpin_user_page(). | |
| 52 | 67 | * |
| 53 | 68 | */ |
| 54 | −void put_user_pages_dirty_lock(struct page **pages, unsigned long npages, | |
| 55 | − bool make_dirty) | |
| 69 | +void unpin_user_pages_dirty_lock(struct page **pages, unsigned long npages, | |
| 70 | + bool make_dirty) | |
| 56 | 71 | { |
| 57 | 72 | unsigned long index; |
| 58 | 73 | |
| @@ -63,7 +78,7 @@ void put_user_pages_dirty_lock(struct page **pages, unsigned long npages, · 4 unmodified lines | ||
| 63 | 78 | */ |
| 64 | 79 | |
| 65 | 80 | if (!make_dirty) { |
| 66 | − put_user_pages(pages, npages); | |
| 81 | + unpin_user_pages(pages, npages); | |
| 67 | 82 | return; |
| 68 | 83 | } |
| 69 | 84 | |
| @@ -91,21 +106,21 @@ void put_user_pages_dirty_lock(struct page **pages, unsigned long npages, · 21 unmodified lines | ||
| 91 | 106 | */ |
| 92 | 107 | if (!PageDirty(page)) |
| 93 | 108 | set_page_dirty_lock(page); |
| 94 | − put_user_page(page); | |
| 109 | + unpin_user_page(page); | |
| 95 | 110 | } |
| 96 | 111 | } |
| 97 | −EXPORT_SYMBOL(put_user_pages_dirty_lock); | |
| 112 | +EXPORT_SYMBOL(unpin_user_pages_dirty_lock); | |
| 98 | 113 | |
| 99 | 114 | /** |
| 100 | − * put_user_pages() - release an array of gup-pinned pages. | |
| 115 | + * unpin_user_pages() - release an array of gup-pinned pages. | |
| 101 | 116 | * @pages: array of pages to be marked dirty and released. |
| 102 | 117 | * @npages: number of pages in the @pages array. |
| 103 | 118 | * |
| 104 | − * For each page in the @pages array, release the page using put_user_page(). | |
| 119 | + * For each page in the @pages array, release the page using unpin_user_page(). | |
| 105 | 120 | * |
| 106 | − * Please see the put_user_page() documentation for details. | |
| 121 | + * Please see the unpin_user_page() documentation for details. | |
| 107 | 122 | */ |
| 108 | −void put_user_pages(struct page **pages, unsigned long npages) | |
| 123 | +void unpin_user_pages(struct page **pages, unsigned long npages) | |
| 109 | 124 | { |
| 110 | 125 | unsigned long index; |
| 111 | 126 | |
| @@ -115,9 +130,9 @@ void put_user_pages(struct page **pages, unsigned long npages) · 3 unmodified lines | ||
| 115 | 130 | * single operation to the head page should suffice. |
| 116 | 131 | */ |
| 117 | 132 | for (index = 0; index < npages; index++) |
| 118 | − put_user_page(pages[index]); | |
| 133 | + unpin_user_page(pages[index]); | |
| 119 | 134 | } |
| 120 | −EXPORT_SYMBOL(put_user_pages); | |
| 135 | +EXPORT_SYMBOL(unpin_user_pages); | |
| 121 | 136 | |
| 122 | 137 | #ifdef CONFIG_MMU |
| 123 | 138 | static struct page *no_page_table(struct vm_area_struct *vma, |
| @@ -179,6 +194,10 @@ static struct page *follow_page_pte(struct vm_area_struct *vma, · 55 unmodified lines | ||
| 179 | 194 | spinlock_t *ptl; |
| 180 | 195 | pte_t *ptep, pte; |
| 181 | 196 | |
| 197 | + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ | |
| 198 | + if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) == | |
| 199 | + (FOLL_PIN | FOLL_GET))) | |
| 200 | + return ERR_PTR(-EINVAL); | |
| 182 | 201 | retry: |
| 183 | 202 | if (unlikely(pmd_bad(*pmd))) |
| 184 | 203 | return no_page_table(vma, flags); |
| @@ -323,7 +342,7 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma, · 138 unmodified lines | ||
| 323 | 342 | pmdval = READ_ONCE(*pmd); |
| 324 | 343 | if (pmd_none(pmdval)) |
| 325 | 344 | return no_page_table(vma, flags); |
| 326 | − if (pmd_huge(pmdval) && vma->vm_flags & VM_HUGETLB) { | |
| 345 | + if (pmd_huge(pmdval) && is_vm_hugetlb_page(vma)) { | |
| 327 | 346 | page = follow_huge_pmd(mm, address, pmd, flags); |
| 328 | 347 | if (page) |
| 329 | 348 | return page; |
| @@ -433,7 +452,7 @@ static struct page *follow_pud_mask(struct vm_area_struct *vma, · 103 unmodified lines | ||
| 433 | 452 | pud = pud_offset(p4dp, address); |
| 434 | 453 | if (pud_none(*pud)) |
| 435 | 454 | return no_page_table(vma, flags); |
| 436 | − if (pud_huge(*pud) && vma->vm_flags & VM_HUGETLB) { | |
| 455 | + if (pud_huge(*pud) && is_vm_hugetlb_page(vma)) { | |
| 437 | 456 | page = follow_huge_pud(mm, address, pud, flags); |
| 438 | 457 | if (page) |
| 439 | 458 | return page; |
| @@ -796,7 +815,7 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, · 356 unmodified lines | ||
| 796 | 815 | |
| 797 | 816 | start = untagged_addr(start); |
| 798 | 817 | |
| 799 | − VM_BUG_ON(!!pages != !!(gup_flags & FOLL_GET)); | |
| 818 | + VM_BUG_ON(!!pages != !!(gup_flags & (FOLL_GET | FOLL_PIN))); | |
| 800 | 819 | |
| 801 | 820 | /* |
| 802 | 821 | * If FOLL_FORCE is set then do not force a full fault as the hinting |
| @@ -1020,7 +1039,16 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, · 217 unmodified lines | ||
| 1020 | 1039 | BUG_ON(*locked != 1); |
| 1021 | 1040 | } |
| 1022 | 1041 | |
| 1023 | − if (pages) | |
| 1042 | + /* | |
| 1043 | + * FOLL_PIN and FOLL_GET are mutually exclusive. Traditional behavior | |
| 1044 | + * is to set FOLL_GET if the caller wants pages[] filled in (but has | |
| 1045 | + * carelessly failed to specify FOLL_GET), so keep doing that, but only | |
| 1046 | + * for FOLL_GET, not for the newer FOLL_PIN. | |
| 1047 | + * | |
| 1048 | + * FOLL_PIN always expects pages to be non-null, but no need to assert | |
| 1049 | + * that here, as any failures will be obvious enough. | |
| 1050 | + */ | |
| 1051 | + if (pages && !(flags & FOLL_PIN)) | |
| 1024 | 1052 | flags |= FOLL_GET; |
| 1025 | 1053 | |
| 1026 | 1054 | pages_done = 0; |
| @@ -1096,88 +1124,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, · 69 unmodified lines | ||
| 1096 | 1124 | return pages_done; |
| 1097 | 1125 | } |
| 1098 | 1126 | |
| 1099 | −/* | |
| 1100 | − * get_user_pages_remote() - pin user pages in memory | |
| 1101 | − * @tsk: the task_struct to use for page fault accounting, or | |
| 1102 | − * NULL if faults are not to be recorded. | |
| 1103 | − * @mm: mm_struct of target mm | |
| 1104 | − * @start: starting user address | |
| 1105 | − * @nr_pages: number of pages from start to pin | |
| 1106 | − * @gup_flags: flags modifying lookup behaviour | |
| 1107 | − * @pages: array that receives pointers to the pages pinned. | |
| 1108 | − * Should be at least nr_pages long. Or NULL, if caller | |
| 1109 | − * only intends to ensure the pages are faulted in. | |
| 1110 | − * @vmas: array of pointers to vmas corresponding to each page. | |
| 1111 | − * Or NULL if the caller does not require them. | |
| 1112 | − * @locked: pointer to lock flag indicating whether lock is held and | |
| 1113 | − * subsequently whether VM_FAULT_RETRY functionality can be | |
| 1114 | − * utilised. Lock must initially be held. | |
| 1115 | − * | |
| 1116 | − * Returns either number of pages pinned (which may be less than the | |
| 1117 | − * number requested), or an error. Details about the return value: | |
| 1118 | − * | |
| 1119 | − * -- If nr_pages is 0, returns 0. | |
| 1120 | − * -- If nr_pages is >0, but no pages were pinned, returns -errno. | |
| 1121 | − * -- If nr_pages is >0, and some pages were pinned, returns the number of | |
| 1122 | − * pages pinned. Again, this may be less than nr_pages. | |
| 1123 | − * | |
| 1124 | − * The caller is responsible for releasing returned @pages, via put_page(). | |
| 1125 | − * | |
| 1126 | − * @vmas are valid only as long as mmap_sem is held. | |
| 1127 | − * | |
| 1128 | − * Must be called with mmap_sem held for read or write. | |
| 1129 | − * | |
| 1130 | − * get_user_pages walks a process's page tables and takes a reference to | |
| 1131 | − * each struct page that each user address corresponds to at a given | |
| 1132 | − * instant. That is, it takes the page that would be accessed if a user | |
| 1133 | − * thread accesses the given user virtual address at that instant. | |
| 1134 | − * | |
| 1135 | − * This does not guarantee that the page exists in the user mappings when | |
| 1136 | − * get_user_pages returns, and there may even be a completely different | |
| 1137 | − * page there in some cases (eg. if mmapped pagecache has been invalidated | |
| 1138 | − * and subsequently re faulted). However it does guarantee that the page | |
| 1139 | − * won't be freed completely. And mostly callers simply care that the page | |
| 1140 | − * contains data that was valid *at some point in time*. Typically, an IO | |
| 1141 | − * or similar operation cannot guarantee anything stronger anyway because | |
| 1142 | − * locks can't be held over the syscall boundary. | |
| 1143 | − * | |
| 1144 | − * If gup_flags & FOLL_WRITE == 0, the page must not be written to. If the page | |
| 1145 | − * is written to, set_page_dirty (or set_page_dirty_lock, as appropriate) must | |
| 1146 | − * be called after the page is finished with, and before put_page is called. | |
| 1147 | − * | |
| 1148 | − * get_user_pages is typically used for fewer-copy IO operations, to get a | |
| 1149 | − * handle on the memory by some means other than accesses via the user virtual | |
| 1150 | − * addresses. The pages may be submitted for DMA to devices or accessed via | |
| 1151 | − * their kernel linear mapping (via the kmap APIs). Care should be taken to | |
| 1152 | − * use the correct cache flushing APIs. | |
| 1153 | − * | |
| 1154 | − * See also get_user_pages_fast, for performance critical applications. | |
| 1155 | − * | |
| 1156 | − * get_user_pages should be phased out in favor of | |
| 1157 | − * get_user_pages_locked|unlocked or get_user_pages_fast. Nothing | |
| 1158 | − * should use get_user_pages because it cannot pass | |
| 1159 | − * FAULT_FLAG_ALLOW_RETRY to handle_mm_fault. | |
| 1160 | − */ | |
| 1161 | −long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, | |
| 1162 | − unsigned long start, unsigned long nr_pages, | |
| 1163 | − unsigned int gup_flags, struct page **pages, | |
| 1164 | − struct vm_area_struct **vmas, int *locked) | |
| 1165 | −{ | |
| 1166 | − /* | |
| 1167 | − * FIXME: Current FOLL_LONGTERM behavior is incompatible with | |
| 1168 | − * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on | |
| 1169 | − * vmas. As there are no users of this flag in this call we simply | |
| 1170 | − * disallow this option for now. | |
| 1171 | − */ | |
| 1172 | − if (WARN_ON_ONCE(gup_flags & FOLL_LONGTERM)) | |
| 1173 | − return -EINVAL; | |
| 1174 | − | |
| 1175 | − return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, | |
| 1176 | − locked, | |
| 1177 | − gup_flags | FOLL_TOUCH | FOLL_REMOTE); | |
| 1178 | −} | |
| 1179 | −EXPORT_SYMBOL(get_user_pages_remote); | |
| 1180 | − | |
| 1181 | 1127 | /** |
| 1182 | 1128 | * populate_vma_page_range() - populate a range of pages in the vma. |
| 1183 | 1129 | * @vma: target vma |
| @@ -1611,6 +1557,116 @@ static __always_inline long __gup_longterm_locked(struct task_struct *tsk, · 427 unmodified lines | ||
| 1611 | 1557 | } |
| 1612 | 1558 | #endif /* CONFIG_FS_DAX || CONFIG_CMA */ |
| 1613 | 1559 | |
| 1560 | +/* | |
| 1561 | + * get_user_pages_remote() - pin user pages in memory | |
| 1562 | + * @tsk: the task_struct to use for page fault accounting, or | |
| 1563 | + * NULL if faults are not to be recorded. | |
| 1564 | + * @mm: mm_struct of target mm | |
| 1565 | + * @start: starting user address | |
| 1566 | + * @nr_pages: number of pages from start to pin | |
| 1567 | + * @gup_flags: flags modifying lookup behaviour | |
| 1568 | + * @pages: array that receives pointers to the pages pinned. | |
| 1569 | + * Should be at least nr_pages long. Or NULL, if caller | |
| 1570 | + * only intends to ensure the pages are faulted in. | |
| 1571 | + * @vmas: array of pointers to vmas corresponding to each page. | |
| 1572 | + * Or NULL if the caller does not require them. | |
| 1573 | + * @locked: pointer to lock flag indicating whether lock is held and | |
| 1574 | + * subsequently whether VM_FAULT_RETRY functionality can be | |
| 1575 | + * utilised. Lock must initially be held. | |
| 1576 | + * | |
| 1577 | + * Returns either number of pages pinned (which may be less than the | |
| 1578 | + * number requested), or an error. Details about the return value: | |
| 1579 | + * | |
| 1580 | + * -- If nr_pages is 0, returns 0. | |
| 1581 | + * -- If nr_pages is >0, but no pages were pinned, returns -errno. | |
| 1582 | + * -- If nr_pages is >0, and some pages were pinned, returns the number of | |
| 1583 | + * pages pinned. Again, this may be less than nr_pages. | |
| 1584 | + * | |
| 1585 | + * The caller is responsible for releasing returned @pages, via put_page(). | |
| 1586 | + * | |
| 1587 | + * @vmas are valid only as long as mmap_sem is held. | |
| 1588 | + * | |
| 1589 | + * Must be called with mmap_sem held for read or write. | |
| 1590 | + * | |
| 1591 | + * get_user_pages walks a process's page tables and takes a reference to | |
| 1592 | + * each struct page that each user address corresponds to at a given | |
| 1593 | + * instant. That is, it takes the page that would be accessed if a user | |
| 1594 | + * thread accesses the given user virtual address at that instant. | |
| 1595 | + * | |
| 1596 | + * This does not guarantee that the page exists in the user mappings when | |
| 1597 | + * get_user_pages returns, and there may even be a completely different | |
| 1598 | + * page there in some cases (eg. if mmapped pagecache has been invalidated | |
| 1599 | + * and subsequently re faulted). However it does guarantee that the page | |
| 1600 | + * won't be freed completely. And mostly callers simply care that the page | |
| 1601 | + * contains data that was valid *at some point in time*. Typically, an IO | |
| 1602 | + * or similar operation cannot guarantee anything stronger anyway because | |
| 1603 | + * locks can't be held over the syscall boundary. | |
| 1604 | + * | |
| 1605 | + * If gup_flags & FOLL_WRITE == 0, the page must not be written to. If the page | |
| 1606 | + * is written to, set_page_dirty (or set_page_dirty_lock, as appropriate) must | |
| 1607 | + * be called after the page is finished with, and before put_page is called. | |
| 1608 | + * | |
| 1609 | + * get_user_pages is typically used for fewer-copy IO operations, to get a | |
| 1610 | + * handle on the memory by some means other than accesses via the user virtual | |
| 1611 | + * addresses. The pages may be submitted for DMA to devices or accessed via | |
| 1612 | + * their kernel linear mapping (via the kmap APIs). Care should be taken to | |
| 1613 | + * use the correct cache flushing APIs. | |
| 1614 | + * | |
| 1615 | + * See also get_user_pages_fast, for performance critical applications. | |
| 1616 | + * | |
| 1617 | + * get_user_pages should be phased out in favor of | |
| 1618 | + * get_user_pages_locked|unlocked or get_user_pages_fast. Nothing | |
| 1619 | + * should use get_user_pages because it cannot pass | |
| 1620 | + * FAULT_FLAG_ALLOW_RETRY to handle_mm_fault. | |
| 1621 | + */ | |
| 1622 | +#ifdef CONFIG_MMU | |
| 1623 | +long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, | |
| 1624 | + unsigned long start, unsigned long nr_pages, | |
| 1625 | + unsigned int gup_flags, struct page **pages, | |
| 1626 | + struct vm_area_struct **vmas, int *locked) | |
| 1627 | +{ | |
| 1628 | + /* | |
| 1629 | + * FOLL_PIN must only be set internally by the pin_user_pages*() APIs, | |
| 1630 | + * never directly by the caller, so enforce that with an assertion: | |
| 1631 | + */ | |
| 1632 | + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) | |
| 1633 | + return -EINVAL; | |
| 1634 | + | |
| 1635 | + /* | |
| 1636 | + * Parts of FOLL_LONGTERM behavior are incompatible with | |
| 1637 | + * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on | |
| 1638 | + * vmas. However, this only comes up if locked is set, and there are | |
| 1639 | + * callers that do request FOLL_LONGTERM, but do not set locked. So, | |
| 1640 | + * allow what we can. | |
| 1641 | + */ | |
| 1642 | + if (gup_flags & FOLL_LONGTERM) { | |
| 1643 | + if (WARN_ON_ONCE(locked)) | |
| 1644 | + return -EINVAL; | |
| 1645 | + /* | |
| 1646 | + * This will check the vmas (even if our vmas arg is NULL) | |
| 1647 | + * and return -ENOTSUPP if DAX isn't allowed in this case: | |
| 1648 | + */ | |
| 1649 | + return __gup_longterm_locked(tsk, mm, start, nr_pages, pages, | |
| 1650 | + vmas, gup_flags | FOLL_TOUCH | | |
| 1651 | + FOLL_REMOTE); | |
| 1652 | + } | |
| 1653 | + | |
| 1654 | + return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, | |
| 1655 | + locked, | |
| 1656 | + gup_flags | FOLL_TOUCH | FOLL_REMOTE); | |
| 1657 | +} | |
| 1658 | +EXPORT_SYMBOL(get_user_pages_remote); | |
| 1659 | + | |
| 1660 | +#else /* CONFIG_MMU */ | |
| 1661 | +long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, | |
| 1662 | + unsigned long start, unsigned long nr_pages, | |
| 1663 | + unsigned int gup_flags, struct page **pages, | |
| 1664 | + struct vm_area_struct **vmas, int *locked) | |
| 1665 | +{ | |
| 1666 | + return 0; | |
| 1667 | +} | |
| 1668 | +#endif /* !CONFIG_MMU */ | |
| 1669 | + | |
| 1614 | 1670 | /* |
| 1615 | 1671 | * This is the same as get_user_pages_remote(), just with a |
| 1616 | 1672 | * less-flexible calling convention where we assume that the task |
| @@ -1622,6 +1678,13 @@ long get_user_pages(unsigned long start, unsigned long nr_pages, · 5 unmodified lines | ||
| 1622 | 1678 | unsigned int gup_flags, struct page **pages, |
| 1623 | 1679 | struct vm_area_struct **vmas) |
| 1624 | 1680 | { |
| 1681 | + /* | |
| 1682 | + * FOLL_PIN must only be set internally by the pin_user_pages*() APIs, | |
| 1683 | + * never directly by the caller, so enforce that with an assertion: | |
| 1684 | + */ | |
| 1685 | + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) | |
| 1686 | + return -EINVAL; | |
| 1687 | + | |
| 1625 | 1688 | return __gup_longterm_locked(current, current->mm, start, nr_pages, |
| 1626 | 1689 | pages, vmas, gup_flags | FOLL_TOUCH); |
| 1627 | 1690 | } |
| @@ -1807,20 +1870,6 @@ static void __maybe_unused undo_dev_pagemap(int *nr, int nr_start, · 179 unmodified lines | ||
| 1807 | 1870 | } |
| 1808 | 1871 | } |
| 1809 | 1872 | |
| 1810 | −/* | |
| 1811 | − * Return the compund head page with ref appropriately incremented, | |
| 1812 | − * or NULL if that failed. | |
| 1813 | − */ | |
| 1814 | −static inline struct page *try_get_compound_head(struct page *page, int refs) | |
| 1815 | −{ | |
| 1816 | − struct page *head = compound_head(page); | |
| 1817 | − if (WARN_ON_ONCE(page_ref_count(head) < 0)) | |
| 1818 | − return NULL; | |
| 1819 | − if (unlikely(!page_cache_add_speculative(head, refs))) | |
| 1820 | − return NULL; | |
| 1821 | − return head; | |
| 1822 | −} | |
| 1823 | − | |
| 1824 | 1873 | #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL |
| 1825 | 1874 | static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end, |
| 1826 | 1875 | unsigned int flags, struct page **pages, int *nr) |
| @@ -1978,6 +2027,29 @@ static int __gup_device_huge_pud(pud_t pud, pud_t *pudp, unsigned long addr, · 151 unmodified lines | ||
| 1978 | 2027 | } |
| 1979 | 2028 | #endif |
| 1980 | 2029 | |
| 2030 | +static int record_subpages(struct page *page, unsigned long addr, | |
| 2031 | + unsigned long end, struct page **pages) | |
| 2032 | +{ | |
| 2033 | + int nr; | |
| 2034 | + | |
| 2035 | + for (nr = 0; addr != end; addr += PAGE_SIZE) | |
| 2036 | + pages[nr++] = page++; | |
| 2037 | + | |
| 2038 | + return nr; | |
| 2039 | +} | |
| 2040 | + | |
| 2041 | +static void put_compound_head(struct page *page, int refs) | |
| 2042 | +{ | |
| 2043 | + VM_BUG_ON_PAGE(page_ref_count(page) < refs, page); | |
| 2044 | + /* | |
| 2045 | + * Calling put_page() for each ref is unnecessarily slow. Only the last | |
| 2046 | + * ref needs a put_page(). | |
| 2047 | + */ | |
| 2048 | + if (refs > 1) | |
| 2049 | + page_ref_sub(page, refs - 1); | |
| 2050 | + put_page(page); | |
| 2051 | +} | |
| 2052 | + | |
| 1981 | 2053 | #ifdef CONFIG_ARCH_HAS_HUGEPD |
| 1982 | 2054 | static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end, |
| 1983 | 2055 | unsigned long sz) |
| @@ -2007,32 +2079,20 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, · 23 unmodified lines | ||
| 2007 | 2079 | /* hugepages are never "special" */ |
| 2008 | 2080 | VM_BUG_ON(!pfn_valid(pte_pfn(pte))); |
| 2009 | 2081 | |
| 2010 | − refs = 0; | |
| 2011 | 2082 | head = pte_page(pte); |
| 2012 | − | |
| 2013 | 2083 | page = head + ((addr & (sz-1)) >> PAGE_SHIFT); |
| 2014 | − do { | |
| 2015 | − VM_BUG_ON(compound_head(page) != head); | |
| 2016 | − pages[*nr] = page; | |
| 2017 | − (*nr)++; | |
| 2018 | − page++; | |
| 2019 | − refs++; | |
| 2020 | − } while (addr += PAGE_SIZE, addr != end); | |
| 2084 | + refs = record_subpages(page, addr, end, pages + *nr); | |
| 2021 | 2085 | |
| 2022 | 2086 | head = try_get_compound_head(head, refs); |
| 2023 | − if (!head) { | |
| 2024 | − *nr -= refs; | |
| 2087 | + if (!head) | |
| 2025 | 2088 | return 0; |
| 2026 | − } | |
| 2027 | 2089 | |
| 2028 | 2090 | if (unlikely(pte_val(pte) != pte_val(*ptep))) { |
| 2029 | − /* Could be optimized better */ | |
| 2030 | − *nr -= refs; | |
| 2031 | − while (refs--) | |
| 2032 | − put_page(head); | |
| 2091 | + put_compound_head(head, refs); | |
| 2033 | 2092 | return 0; |
| 2034 | 2093 | } |
| 2035 | 2094 | |
| 2095 | + *nr += refs; | |
| 2036 | 2096 | SetPageReferenced(head); |
| 2037 | 2097 | return 1; |
| 2038 | 2098 | } |
| @@ -2079,28 +2139,19 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr, · 40 unmodified lines | ||
| 2079 | 2139 | return __gup_device_huge_pmd(orig, pmdp, addr, end, pages, nr); |
| 2080 | 2140 | } |
| 2081 | 2141 | |
| 2082 | − refs = 0; | |
| 2083 | 2142 | page = pmd_page(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT); |
| 2084 | − do { | |
| 2085 | − pages[*nr] = page; | |
| 2086 | − (*nr)++; | |
| 2087 | − page++; | |
| 2088 | − refs++; | |
| 2089 | − } while (addr += PAGE_SIZE, addr != end); | |
| 2143 | + refs = record_subpages(page, addr, end, pages + *nr); | |
| 2090 | 2144 | |
| 2091 | 2145 | head = try_get_compound_head(pmd_page(orig), refs); |
| 2092 | − if (!head) { | |
| 2093 | − *nr -= refs; | |
| 2146 | + if (!head) | |
| 2094 | 2147 | return 0; |
| 2095 | − } | |
| 2096 | 2148 | |
| 2097 | 2149 | if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) { |
| 2098 | − *nr -= refs; | |
| 2099 | − while (refs--) | |
| 2100 | − put_page(head); | |
| 2150 | + put_compound_head(head, refs); | |
| 2101 | 2151 | return 0; |
| 2102 | 2152 | } |
| 2103 | 2153 | |
| 2154 | + *nr += refs; | |
| 2104 | 2155 | SetPageReferenced(head); |
| 2105 | 2156 | return 1; |
| 2106 | 2157 | } |
| @@ -2120,28 +2171,19 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr, · 13 unmodified lines | ||
| 2120 | 2171 | return __gup_device_huge_pud(orig, pudp, addr, end, pages, nr); |
| 2121 | 2172 | } |
| 2122 | 2173 | |
| 2123 | − refs = 0; | |
| 2124 | 2174 | page = pud_page(orig) + ((addr & ~PUD_MASK) >> PAGE_SHIFT); |
| 2125 | − do { | |
| 2126 | − pages[*nr] = page; | |
| 2127 | − (*nr)++; | |
| 2128 | − page++; | |
| 2129 | − refs++; | |
| 2130 | − } while (addr += PAGE_SIZE, addr != end); | |
| 2175 | + refs = record_subpages(page, addr, end, pages + *nr); | |
| 2131 | 2176 | |
| 2132 | 2177 | head = try_get_compound_head(pud_page(orig), refs); |
| 2133 | − if (!head) { | |
| 2134 | − *nr -= refs; | |
| 2178 | + if (!head) | |
| 2135 | 2179 | return 0; |
| 2136 | − } | |
| 2137 | 2180 | |
| 2138 | 2181 | if (unlikely(pud_val(orig) != pud_val(*pudp))) { |
| 2139 | − *nr -= refs; | |
| 2140 | − while (refs--) | |
| 2141 | − put_page(head); | |
| 2182 | + put_compound_head(head, refs); | |
| 2142 | 2183 | return 0; |
| 2143 | 2184 | } |
| 2144 | 2185 | |
| 2186 | + *nr += refs; | |
| 2145 | 2187 | SetPageReferenced(head); |
| 2146 | 2188 | return 1; |
| 2147 | 2189 | } |
| @@ -2157,28 +2199,20 @@ static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, unsigned long addr, · 9 unmodified lines | ||
| 2157 | 2199 | return 0; |
| 2158 | 2200 | |
| 2159 | 2201 | BUILD_BUG_ON(pgd_devmap(orig)); |
| 2160 | − refs = 0; | |
| 2202 | + | |
| 2161 | 2203 | page = pgd_page(orig) + ((addr & ~PGDIR_MASK) >> PAGE_SHIFT); |
| 2162 | − do { | |
| 2163 | − pages[*nr] = page; | |
| 2164 | − (*nr)++; | |
| 2165 | − page++; | |
| 2166 | − refs++; | |
| 2167 | − } while (addr += PAGE_SIZE, addr != end); | |
| 2204 | + refs = record_subpages(page, addr, end, pages + *nr); | |
| 2168 | 2205 | |
| 2169 | 2206 | head = try_get_compound_head(pgd_page(orig), refs); |
| 2170 | − if (!head) { | |
| 2171 | − *nr -= refs; | |
| 2207 | + if (!head) | |
| 2172 | 2208 | return 0; |
| 2173 | − } | |
| 2174 | 2209 | |
| 2175 | 2210 | if (unlikely(pgd_val(orig) != pgd_val(*pgdp))) { |
| 2176 | − *nr -= refs; | |
| 2177 | − while (refs--) | |
| 2178 | − put_page(head); | |
| 2211 | + put_compound_head(head, refs); | |
| 2179 | 2212 | return 0; |
| 2180 | 2213 | } |
| 2181 | 2214 | |
| 2215 | + *nr += refs; | |
| 2182 | 2216 | SetPageReferenced(head); |
| 2183 | 2217 | return 1; |
| 2184 | 2218 | } |
| @@ -2237,7 +2271,7 @@ static int gup_pud_range(p4d_t p4d, unsigned long addr, unsigned long end, · 52 unmodified lines | ||
| 2237 | 2271 | pud_t pud = READ_ONCE(*pudp); |
| 2238 | 2272 | |
| 2239 | 2273 | next = pud_addr_end(addr, end); |
| 2240 | − if (pud_none(pud)) | |
| 2274 | + if (unlikely(!pud_present(pud))) | |
| 2241 | 2275 | return 0; |
| 2242 | 2276 | if (unlikely(pud_huge(pud))) { |
| 2243 | 2277 | if (!gup_huge_pud(pud, pudp, addr, next, flags, |
| @@ -2393,29 +2427,15 @@ static int __gup_longterm_unlocked(unsigned long start, int nr_pages, · 149 unmodified lines | ||
| 2393 | 2427 | return ret; |
| 2394 | 2428 | } |
| 2395 | 2429 | |
| 2396 | −/** | |
| 2397 | − * get_user_pages_fast() - pin user pages in memory | |
| 2398 | − * @start: starting user address | |
| 2399 | − * @nr_pages: number of pages from start to pin | |
| 2400 | − * @gup_flags: flags modifying pin behaviour | |
| 2401 | − * @pages: array that receives pointers to the pages pinned. | |
| 2402 | − * Should be at least nr_pages long. | |
| 2403 | − * | |
| 2404 | − * Attempt to pin user pages in memory without taking mm->mmap_sem. | |
| 2405 | − * If not successful, it will fall back to taking the lock and | |
| 2406 | − * calling get_user_pages(). | |
| 2407 | − * | |
| 2408 | − * Returns number of pages pinned. This may be fewer than the number | |
| 2409 | − * requested. If nr_pages is 0 or negative, returns 0. If no pages | |
| 2410 | − * were pinned, returns -errno. | |
| 2411 | − */ | |
| 2412 | −int get_user_pages_fast(unsigned long start, int nr_pages, | |
| 2413 | − unsigned int gup_flags, struct page **pages) | |
| 2430 | +static int internal_get_user_pages_fast(unsigned long start, int nr_pages, | |
| 2431 | + unsigned int gup_flags, | |
| 2432 | + struct page **pages) | |
| 2414 | 2433 | { |
| 2415 | 2434 | unsigned long addr, len, end; |
| 2416 | 2435 | int nr = 0, ret = 0; |
| 2417 | 2436 | |
| 2418 | − if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM))) | |
| 2437 | + if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM | | |
| 2438 | + FOLL_FORCE | FOLL_PIN))) | |
| 2419 | 2439 | return -EINVAL; |
| 2420 | 2440 | |
| 2421 | 2441 | start = untagged_addr(start) & PAGE_MASK; |
| @@ -2455,4 +2475,103 @@ int get_user_pages_fast(unsigned long start, int nr_pages, · 33 unmodified lines | ||
| 2455 | 2475 | |
| 2456 | 2476 | return ret; |
| 2457 | 2477 | } |
| 2478 | + | |
| 2479 | +/** | |
| 2480 | + * get_user_pages_fast() - pin user pages in memory | |
| 2481 | + * @start: starting user address | |
| 2482 | + * @nr_pages: number of pages from start to pin | |
| 2483 | + * @gup_flags: flags modifying pin behaviour | |
| 2484 | + * @pages: array that receives pointers to the pages pinned. | |
| 2485 | + * Should be at least nr_pages long. | |
| 2486 | + * | |
| 2487 | + * Attempt to pin user pages in memory without taking mm->mmap_sem. | |
| 2488 | + * If not successful, it will fall back to taking the lock and | |
| 2489 | + * calling get_user_pages(). | |
| 2490 | + * | |
| 2491 | + * Returns number of pages pinned. This may be fewer than the number requested. | |
| 2492 | + * If nr_pages is 0 or negative, returns 0. If no pages were pinned, returns | |
| 2493 | + * -errno. | |
| 2494 | + */ | |
| 2495 | +int get_user_pages_fast(unsigned long start, int nr_pages, | |
| 2496 | + unsigned int gup_flags, struct page **pages) | |
| 2497 | +{ | |
| 2498 | + /* | |
| 2499 | + * FOLL_PIN must only be set internally by the pin_user_pages*() APIs, | |
| 2500 | + * never directly by the caller, so enforce that: | |
| 2501 | + */ | |
| 2502 | + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) | |
| 2503 | + return -EINVAL; | |
| 2504 | + | |
| 2505 | + return internal_get_user_pages_fast(start, nr_pages, gup_flags, pages); | |
| 2506 | +} | |
| 2458 | 2507 | EXPORT_SYMBOL_GPL(get_user_pages_fast); |
| 2508 | + | |
| 2509 | +/** | |
| 2510 | + * pin_user_pages_fast() - pin user pages in memory without taking locks | |
| 2511 | + * | |
| 2512 | + * For now, this is a placeholder function, until various call sites are | |
| 2513 | + * converted to use the correct get_user_pages*() or pin_user_pages*() API. So, | |
| 2514 | + * this is identical to get_user_pages_fast(). | |
| 2515 | + * | |
| 2516 | + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It | |
| 2517 | + * is NOT intended for Case 2 (RDMA: long-term pins). | |
| 2518 | + */ | |
| 2519 | +int pin_user_pages_fast(unsigned long start, int nr_pages, | |
| 2520 | + unsigned int gup_flags, struct page **pages) | |
| 2521 | +{ | |
| 2522 | + /* | |
| 2523 | + * This is a placeholder, until the pin functionality is activated. | |
| 2524 | + * Until then, just behave like the corresponding get_user_pages*() | |
| 2525 | + * routine. | |
| 2526 | + */ | |
| 2527 | + return get_user_pages_fast(start, nr_pages, gup_flags, pages); | |
| 2528 | +} | |
| 2529 | +EXPORT_SYMBOL_GPL(pin_user_pages_fast); | |
| 2530 | + | |
| 2531 | +/** | |
| 2532 | + * pin_user_pages_remote() - pin pages of a remote process (task != current) | |
| 2533 | + * | |
| 2534 | + * For now, this is a placeholder function, until various call sites are | |
| 2535 | + * converted to use the correct get_user_pages*() or pin_user_pages*() API. So, | |
| 2536 | + * this is identical to get_user_pages_remote(). | |
| 2537 | + * | |
| 2538 | + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It | |
| 2539 | + * is NOT intended for Case 2 (RDMA: long-term pins). | |
| 2540 | + */ | |
| 2541 | +long pin_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, | |
| 2542 | + unsigned long start, unsigned long nr_pages, | |
| 2543 | + unsigned int gup_flags, struct page **pages, | |
| 2544 | + struct vm_area_struct **vmas, int *locked) | |
| 2545 | +{ | |
| 2546 | + /* | |
| 2547 | + * This is a placeholder, until the pin functionality is activated. | |
| 2548 | + * Until then, just behave like the corresponding get_user_pages*() | |
| 2549 | + * routine. | |
| 2550 | + */ | |
| 2551 | + return get_user_pages_remote(tsk, mm, start, nr_pages, gup_flags, pages, | |
| 2552 | + vmas, locked); | |
| 2553 | +} | |
| 2554 | +EXPORT_SYMBOL(pin_user_pages_remote); | |
| 2555 | + | |
| 2556 | +/** | |
| 2557 | + * pin_user_pages() - pin user pages in memory for use by other devices | |
| 2558 | + * | |
| 2559 | + * For now, this is a placeholder function, until various call sites are | |
| 2560 | + * converted to use the correct get_user_pages*() or pin_user_pages*() API. So, | |
| 2561 | + * this is identical to get_user_pages(). | |
| 2562 | + * | |
| 2563 | + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It | |
| 2564 | + * is NOT intended for Case 2 (RDMA: long-term pins). | |
| 2565 | + */ | |
| 2566 | +long pin_user_pages(unsigned long start, unsigned long nr_pages, | |
| 2567 | + unsigned int gup_flags, struct page **pages, | |
| 2568 | + struct vm_area_struct **vmas) | |
| 2569 | +{ | |
| 2570 | + /* | |
| 2571 | + * This is a placeholder, until the pin functionality is activated. | |
| 2572 | + * Until then, just behave like the corresponding get_user_pages*() | |
| 2573 | + * routine. | |
| 2574 | + */ | |
| 2575 | + return get_user_pages(start, nr_pages, gup_flags, pages, vmas); | |
| 2576 | +} | |
| 2577 | +EXPORT_SYMBOL(pin_user_pages); | |
| @@ -49,18 +49,21 @@ static int __gup_benchmark_ioctl(unsigned int cmd, · 48 unmodified lines | ||
| 49 | 49 | nr = (next - addr) / PAGE_SIZE; |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | + /* Filter out most gup flags: only allow a tiny subset here: */ | |
| 53 | + gup->flags &= FOLL_WRITE; | |
| 54 | + | |
| 52 | 55 | switch (cmd) { |
| 53 | 56 | case GUP_FAST_BENCHMARK: |
| 54 | − nr = get_user_pages_fast(addr, nr, gup->flags & 1, | |
| 57 | + nr = get_user_pages_fast(addr, nr, gup->flags, | |
| 55 | 58 | pages + i); |
| 56 | 59 | break; |
| 57 | 60 | case GUP_LONGTERM_BENCHMARK: |
| 58 | 61 | nr = get_user_pages(addr, nr, |
| 59 | − (gup->flags & 1) | FOLL_LONGTERM, | |
| 62 | + gup->flags | FOLL_LONGTERM, | |
| 60 | 63 | pages + i, NULL); |
| 61 | 64 | break; |
| 62 | 65 | case GUP_BENCHMARK: |
| 63 | − nr = get_user_pages(addr, nr, gup->flags & 1, pages + i, | |
| 66 | + nr = get_user_pages(addr, nr, gup->flags, pages + i, | |
| 64 | 67 | NULL); |
| 65 | 68 | break; |
| 66 | 69 | default: |
| @@ -177,16 +177,13 @@ static ssize_t enabled_store(struct kobject *kobj, · 176 unmodified lines | ||
| 177 | 177 | { |
| 178 | 178 | ssize_t ret = count; |
| 179 | 179 | |
| 180 | − if (!memcmp("always", buf, | |
| 181 | − min(sizeof("always")-1, count))) { | |
| 180 | + if (sysfs_streq(buf, "always")) { | |
| 182 | 181 | clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); |
| 183 | 182 | set_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); |
| 184 | − } else if (!memcmp("madvise", buf, | |
| 185 | − min(sizeof("madvise")-1, count))) { | |
| 183 | + } else if (sysfs_streq(buf, "madvise")) { | |
| 186 | 184 | clear_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); |
| 187 | 185 | set_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); |
| 188 | − } else if (!memcmp("never", buf, | |
| 189 | − min(sizeof("never")-1, count))) { | |
| 186 | + } else if (sysfs_streq(buf, "never")) { | |
| 190 | 187 | clear_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); |
| 191 | 188 | clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); |
| 192 | 189 | } else |
| @@ -250,32 +247,27 @@ static ssize_t defrag_store(struct kobject *kobj, · 57 unmodified lines | ||
| 250 | 247 | struct kobj_attribute *attr, |
| 251 | 248 | const char *buf, size_t count) |
| 252 | 249 | { |
| 253 | − if (!memcmp("always", buf, | |
| 254 | − min(sizeof("always")-1, count))) { | |
| 250 | + if (sysfs_streq(buf, "always")) { | |
| 255 | 251 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); |
| 256 | 252 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); |
| 257 | 253 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); |
| 258 | 254 | set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); |
| 259 | − } else if (!memcmp("defer+madvise", buf, | |
| 260 | − min(sizeof("defer+madvise")-1, count))) { | |
| 255 | + } else if (sysfs_streq(buf, "defer+madvise")) { | |
| 261 | 256 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); |
| 262 | 257 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); |
| 263 | 258 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); |
| 264 | 259 | set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); |
| 265 | − } else if (!memcmp("defer", buf, | |
| 266 | − min(sizeof("defer")-1, count))) { | |
| 260 | + } else if (sysfs_streq(buf, "defer")) { | |
| 267 | 261 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); |
| 268 | 262 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); |
| 269 | 263 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); |
| 270 | 264 | set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); |
| 271 | − } else if (!memcmp("madvise", buf, | |
| 272 | − min(sizeof("madvise")-1, count))) { | |
| 265 | + } else if (sysfs_streq(buf, "madvise")) { | |
| 273 | 266 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); |
| 274 | 267 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); |
| 275 | 268 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); |
| 276 | 269 | set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); |
| 277 | − } else if (!memcmp("never", buf, | |
| 278 | − min(sizeof("never")-1, count))) { | |
| 270 | + } else if (sysfs_streq(buf, "never")) { | |
| 279 | 271 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); |
| 280 | 272 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); |
| 281 | 273 | clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); |
| @@ -2715,7 +2707,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) · 2433 unmodified lines | ||
| 2715 | 2707 | { |
| 2716 | 2708 | struct page *head = compound_head(page); |
| 2717 | 2709 | struct pglist_data *pgdata = NODE_DATA(page_to_nid(head)); |
| 2718 | − struct deferred_split *ds_queue = get_deferred_split_queue(page); | |
| 2710 | + struct deferred_split *ds_queue = get_deferred_split_queue(head); | |
| 2719 | 2711 | struct anon_vma *anon_vma = NULL; |
| 2720 | 2712 | struct address_space *mapping = NULL; |
| 2721 | 2713 | int count, mapcount, extra_pins, ret; |
| @@ -2723,11 +2715,11 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) · 1 unmodified line | ||
| 2723 | 2715 | unsigned long flags; |
| 2724 | 2716 | pgoff_t end; |
| 2725 | 2717 | |
| 2726 | − VM_BUG_ON_PAGE(is_huge_zero_page(page), page); | |
| 2727 | − VM_BUG_ON_PAGE(!PageLocked(page), page); | |
| 2728 | − VM_BUG_ON_PAGE(!PageCompound(page), page); | |
| 2718 | + VM_BUG_ON_PAGE(is_huge_zero_page(head), head); | |
| 2719 | + VM_BUG_ON_PAGE(!PageLocked(head), head); | |
| 2720 | + VM_BUG_ON_PAGE(!PageCompound(head), head); | |
| 2729 | 2721 | |
| 2730 | − if (PageWriteback(page)) | |
| 2722 | + if (PageWriteback(head)) | |
| 2731 | 2723 | return -EBUSY; |
| 2732 | 2724 | |
| 2733 | 2725 | if (PageAnon(head)) { |
| @@ -2778,7 +2770,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) · 44 unmodified lines | ||
| 2778 | 2770 | goto out_unlock; |
| 2779 | 2771 | } |
| 2780 | 2772 | |
| 2781 | − mlocked = PageMlocked(page); | |
| 2773 | + mlocked = PageMlocked(head); | |
| 2782 | 2774 | unmap_page(head); |
| 2783 | 2775 | VM_BUG_ON_PAGE(compound_mapcount(head), head); |
| 2784 | 2776 | |
| @@ -2810,14 +2802,14 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) · 25 unmodified lines | ||
| 2810 | 2802 | ds_queue->split_queue_len--; |
| 2811 | 2803 | list_del(page_deferred_list(head)); |
| 2812 | 2804 | } |
| 2805 | + spin_unlock(&ds_queue->split_queue_lock); | |
| 2813 | 2806 | if (mapping) { |
| 2814 | − if (PageSwapBacked(page)) | |
| 2815 | − __dec_node_page_state(page, NR_SHMEM_THPS); | |
| 2807 | + if (PageSwapBacked(head)) | |
| 2808 | + __dec_node_page_state(head, NR_SHMEM_THPS); | |
| 2816 | 2809 | else |
| 2817 | − __dec_node_page_state(page, NR_FILE_THPS); | |
| 2810 | + __dec_node_page_state(head, NR_FILE_THPS); | |
| 2818 | 2811 | } |
| 2819 | 2812 | |
| 2820 | − spin_unlock(&ds_queue->split_queue_lock); | |
| 2821 | 2813 | __split_huge_page(page, list, end, flags); |
| 2822 | 2814 | if (PageSwapCache(head)) { |
| 2823 | 2815 | swp_entry_t entry = { .val = page_private(head) }; |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | * |
| 14 | 14 | * The following locks and mutexes are used by kmemleak: |
| 15 | 15 | * |
| 16 | − * - kmemleak_lock (rwlock): protects the object_list modifications and | |
| 16 | + * - kmemleak_lock (raw_spinlock_t): protects the object_list modifications and | |
| 17 | 17 | * accesses to the object_tree_root. The object_list is the main list |
| 18 | 18 | * holding the metadata (struct kmemleak_object) for the allocated memory |
| 19 | 19 | * blocks. The object_tree_root is a red black tree used to look-up |
| @@ -22,13 +22,13 @@ · 2 unmodified lines | ||
| 22 | 22 | * object_tree_root in the create_object() function called from the |
| 23 | 23 | * kmemleak_alloc() callback and removed in delete_object() called from the |
| 24 | 24 | * kmemleak_free() callback |
| 25 | − * - kmemleak_object.lock (spinlock): protects a kmemleak_object. Accesses to | |
| 26 | − * the metadata (e.g. count) are protected by this lock. Note that some | |
| 27 | − * members of this structure may be protected by other means (atomic or | |
| 28 | − * kmemleak_lock). This lock is also held when scanning the corresponding | |
| 29 | − * memory block to avoid the kernel freeing it via the kmemleak_free() | |
| 30 | − * callback. This is less heavyweight than holding a global lock like | |
| 31 | − * kmemleak_lock during scanning | |
| 25 | + * - kmemleak_object.lock (raw_spinlock_t): protects a kmemleak_object. | |
| 26 | + * Accesses to the metadata (e.g. count) are protected by this lock. Note | |
| 27 | + * that some members of this structure may be protected by other means | |
| 28 | + * (atomic or kmemleak_lock). This lock is also held when scanning the | |
| 29 | + * corresponding memory block to avoid the kernel freeing it via the | |
| 30 | + * kmemleak_free() callback. This is less heavyweight than holding a global | |
| 31 | + * lock like kmemleak_lock during scanning. | |
| 32 | 32 | * - scan_mutex (mutex): ensures that only one thread may scan the memory for |
| 33 | 33 | * unreferenced objects at a time. The gray_list contains the objects which |
| 34 | 34 | * are already referenced or marked as false positives and need to be |
| @@ -135,7 +135,7 @@ struct kmemleak_scan_area { · 100 unmodified lines | ||
| 135 | 135 | * (use_count) and freed using the RCU mechanism. |
| 136 | 136 | */ |
| 137 | 137 | struct kmemleak_object { |
| 138 | − spinlock_t lock; | |
| 138 | + raw_spinlock_t lock; | |
| 139 | 139 | unsigned int flags; /* object status flags */ |
| 140 | 140 | struct list_head object_list; |
| 141 | 141 | struct list_head gray_list; |
| @@ -191,8 +191,8 @@ static int mem_pool_free_count = ARRAY_SIZE(mem_pool); · 49 unmodified lines | ||
| 191 | 191 | static LIST_HEAD(mem_pool_free_list); |
| 192 | 192 | /* search tree for object boundaries */ |
| 193 | 193 | static struct rb_root object_tree_root = RB_ROOT; |
| 194 | −/* rw_lock protecting the access to object_list and object_tree_root */ | |
| 195 | −static DEFINE_RWLOCK(kmemleak_lock); | |
| 194 | +/* protecting the access to object_list and object_tree_root */ | |
| 195 | +static DEFINE_RAW_SPINLOCK(kmemleak_lock); | |
| 196 | 196 | |
| 197 | 197 | /* allocation caches for kmemleak internal data */ |
| 198 | 198 | static struct kmem_cache *object_cache; |
| @@ -426,7 +426,7 @@ static struct kmemleak_object *mem_pool_alloc(gfp_t gfp) · 227 unmodified lines | ||
| 426 | 426 | } |
| 427 | 427 | |
| 428 | 428 | /* slab allocation failed, try the memory pool */ |
| 429 | − write_lock_irqsave(&kmemleak_lock, flags); | |
| 429 | + raw_spin_lock_irqsave(&kmemleak_lock, flags); | |
| 430 | 430 | object = list_first_entry_or_null(&mem_pool_free_list, |
| 431 | 431 | typeof(*object), object_list); |
| 432 | 432 | if (object) |
| @@ -435,7 +435,7 @@ static struct kmemleak_object *mem_pool_alloc(gfp_t gfp) · 2 unmodified lines | ||
| 435 | 435 | object = &mem_pool[--mem_pool_free_count]; |
| 436 | 436 | else |
| 437 | 437 | pr_warn_once("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n"); |
| 438 | − write_unlock_irqrestore(&kmemleak_lock, flags); | |
| 438 | + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); | |
| 439 | 439 | |
| 440 | 440 | return object; |
| 441 | 441 | } |
| @@ -453,9 +453,9 @@ static void mem_pool_free(struct kmemleak_object *object) · 11 unmodified lines | ||
| 453 | 453 | } |
| 454 | 454 | |
| 455 | 455 | /* add the object to the memory pool free list */ |
| 456 | − write_lock_irqsave(&kmemleak_lock, flags); | |
| 456 | + raw_spin_lock_irqsave(&kmemleak_lock, flags); | |
| 457 | 457 | list_add(&object->object_list, &mem_pool_free_list); |
| 458 | − write_unlock_irqrestore(&kmemleak_lock, flags); | |
| 458 | + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); | |
| 459 | 459 | } |
| 460 | 460 | |
| 461 | 461 | /* |
| @@ -514,9 +514,9 @@ static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias) · 52 unmodified lines | ||
| 514 | 514 | struct kmemleak_object *object; |
| 515 | 515 | |
| 516 | 516 | rcu_read_lock(); |
| 517 | − read_lock_irqsave(&kmemleak_lock, flags); | |
| 517 | + raw_spin_lock_irqsave(&kmemleak_lock, flags); | |
| 518 | 518 | object = lookup_object(ptr, alias); |
| 519 | − read_unlock_irqrestore(&kmemleak_lock, flags); | |
| 519 | + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); | |
| 520 | 520 | |
| 521 | 521 | /* check whether the object is still available */ |
| 522 | 522 | if (object && !get_object(object)) |
| @@ -546,11 +546,11 @@ static struct kmemleak_object *find_and_remove_object(unsigned long ptr, int ali · 23 unmodified lines | ||
| 546 | 546 | unsigned long flags; |
| 547 | 547 | struct kmemleak_object *object; |
| 548 | 548 | |
| 549 | − write_lock_irqsave(&kmemleak_lock, flags); | |
| 549 | + raw_spin_lock_irqsave(&kmemleak_lock, flags); | |
| 550 | 550 | object = lookup_object(ptr, alias); |
| 551 | 551 | if (object) |
| 552 | 552 | __remove_object(object); |
| 553 | − write_unlock_irqrestore(&kmemleak_lock, flags); | |
| 553 | + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); | |
| 554 | 554 | |
| 555 | 555 | return object; |
| 556 | 556 | } |
| @@ -585,7 +585,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, · 28 unmodified lines | ||
| 585 | 585 | INIT_LIST_HEAD(&object->object_list); |
| 586 | 586 | INIT_LIST_HEAD(&object->gray_list); |
| 587 | 587 | INIT_HLIST_HEAD(&object->area_list); |
| 588 | − spin_lock_init(&object->lock); | |
| 588 | + raw_spin_lock_init(&object->lock); | |
| 589 | 589 | atomic_set(&object->use_count, 1); |
| 590 | 590 | object->flags = OBJECT_ALLOCATED; |
| 591 | 591 | object->pointer = ptr; |
| @@ -617,7 +617,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, · 25 unmodified lines | ||
| 617 | 617 | /* kernel backtrace */ |
| 618 | 618 | object->trace_len = __save_stack_trace(object->trace); |
| 619 | 619 | |
| 620 | − write_lock_irqsave(&kmemleak_lock, flags); | |
| 620 | + raw_spin_lock_irqsave(&kmemleak_lock, flags); | |
| 621 | 621 | |
| 622 | 622 | untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); |
| 623 | 623 | min_addr = min(min_addr, untagged_ptr); |
| @@ -649,7 +649,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, · 25 unmodified lines | ||
| 649 | 649 | |
| 650 | 650 | list_add_tail_rcu(&object->object_list, &object_list); |
| 651 | 651 | out: |
| 652 | − write_unlock_irqrestore(&kmemleak_lock, flags); | |
| 652 | + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); | |
| 653 | 653 | return object; |
| 654 | 654 | } |
| 655 | 655 | |
| @@ -667,9 +667,9 @@ static void __delete_object(struct kmemleak_object *object) · 11 unmodified lines | ||
| 667 | 667 | * Locking here also ensures that the corresponding memory block |
| 668 | 668 | * cannot be freed when it is being scanned. |
| 669 | 669 | */ |
| 670 | − spin_lock_irqsave(&object->lock, flags); | |
| 670 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 671 | 671 | object->flags &= ~OBJECT_ALLOCATED; |
| 672 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 672 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 673 | 673 | put_object(object); |
| 674 | 674 | } |
| 675 | 675 | |
| @@ -739,9 +739,9 @@ static void paint_it(struct kmemleak_object *object, int color) · 63 unmodified lines | ||
| 739 | 739 | { |
| 740 | 740 | unsigned long flags; |
| 741 | 741 | |
| 742 | − spin_lock_irqsave(&object->lock, flags); | |
| 742 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 743 | 743 | __paint_it(object, color); |
| 744 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 744 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 745 | 745 | } |
| 746 | 746 | |
| 747 | 747 | static void paint_ptr(unsigned long ptr, int color) |
| @@ -798,7 +798,7 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) · 50 unmodified lines | ||
| 798 | 798 | if (scan_area_cache) |
| 799 | 799 | area = kmem_cache_alloc(scan_area_cache, gfp_kmemleak_mask(gfp)); |
| 800 | 800 | |
| 801 | − spin_lock_irqsave(&object->lock, flags); | |
| 801 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 802 | 802 | if (!area) { |
| 803 | 803 | pr_warn_once("Cannot allocate a scan area, scanning the full object\n"); |
| 804 | 804 | /* mark the object for full scan to avoid false positives */ |
| @@ -820,7 +820,7 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) · 15 unmodified lines | ||
| 820 | 820 | |
| 821 | 821 | hlist_add_head(&area->node, &object->area_list); |
| 822 | 822 | out_unlock: |
| 823 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 823 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 824 | 824 | put_object(object); |
| 825 | 825 | } |
| 826 | 826 | |
| @@ -842,9 +842,9 @@ static void object_set_excess_ref(unsigned long ptr, unsigned long excess_ref) · 15 unmodified lines | ||
| 842 | 842 | return; |
| 843 | 843 | } |
| 844 | 844 | |
| 845 | − spin_lock_irqsave(&object->lock, flags); | |
| 845 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 846 | 846 | object->excess_ref = excess_ref; |
| 847 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 847 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 848 | 848 | put_object(object); |
| 849 | 849 | } |
| 850 | 850 | |
| @@ -864,9 +864,9 @@ static void object_no_scan(unsigned long ptr) · 13 unmodified lines | ||
| 864 | 864 | return; |
| 865 | 865 | } |
| 866 | 866 | |
| 867 | − spin_lock_irqsave(&object->lock, flags); | |
| 867 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 868 | 868 | object->flags |= OBJECT_NO_SCAN; |
| 869 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 869 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 870 | 870 | put_object(object); |
| 871 | 871 | } |
| 872 | 872 | |
| @@ -1026,9 +1026,9 @@ void __ref kmemleak_update_trace(const void *ptr) · 153 unmodified lines | ||
| 1026 | 1026 | return; |
| 1027 | 1027 | } |
| 1028 | 1028 | |
| 1029 | − spin_lock_irqsave(&object->lock, flags); | |
| 1029 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1030 | 1030 | object->trace_len = __save_stack_trace(object->trace); |
| 1031 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1031 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1032 | 1032 | |
| 1033 | 1033 | put_object(object); |
| 1034 | 1034 | } |
| @@ -1233,7 +1233,7 @@ static void scan_block(void *_start, void *_end, · 198 unmodified lines | ||
| 1233 | 1233 | unsigned long flags; |
| 1234 | 1234 | unsigned long untagged_ptr; |
| 1235 | 1235 | |
| 1236 | − read_lock_irqsave(&kmemleak_lock, flags); | |
| 1236 | + raw_spin_lock_irqsave(&kmemleak_lock, flags); | |
| 1237 | 1237 | for (ptr = start; ptr < end; ptr++) { |
| 1238 | 1238 | struct kmemleak_object *object; |
| 1239 | 1239 | unsigned long pointer; |
| @@ -1268,7 +1268,7 @@ static void scan_block(void *_start, void *_end, · 28 unmodified lines | ||
| 1268 | 1268 | * previously acquired in scan_object(). These locks are |
| 1269 | 1269 | * enclosed by scan_mutex. |
| 1270 | 1270 | */ |
| 1271 | − spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); | |
| 1271 | + raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); | |
| 1272 | 1272 | /* only pass surplus references (object already gray) */ |
| 1273 | 1273 | if (color_gray(object)) { |
| 1274 | 1274 | excess_ref = object->excess_ref; |
| @@ -1277,7 +1277,7 @@ static void scan_block(void *_start, void *_end, · 2 unmodified lines | ||
| 1277 | 1277 | excess_ref = 0; |
| 1278 | 1278 | update_refs(object); |
| 1279 | 1279 | } |
| 1280 | − spin_unlock(&object->lock); | |
| 1280 | + raw_spin_unlock(&object->lock); | |
| 1281 | 1281 | |
| 1282 | 1282 | if (excess_ref) { |
| 1283 | 1283 | object = lookup_object(excess_ref, 0); |
| @@ -1286,12 +1286,12 @@ static void scan_block(void *_start, void *_end, · 2 unmodified lines | ||
| 1286 | 1286 | if (object == scanned) |
| 1287 | 1287 | /* circular reference, ignore */ |
| 1288 | 1288 | continue; |
| 1289 | − spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); | |
| 1289 | + raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); | |
| 1290 | 1290 | update_refs(object); |
| 1291 | − spin_unlock(&object->lock); | |
| 1291 | + raw_spin_unlock(&object->lock); | |
| 1292 | 1292 | } |
| 1293 | 1293 | } |
| 1294 | − read_unlock_irqrestore(&kmemleak_lock, flags); | |
| 1294 | + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); | |
| 1295 | 1295 | } |
| 1296 | 1296 | |
| 1297 | 1297 | /* |
| @@ -1324,7 +1324,7 @@ static void scan_object(struct kmemleak_object *object) · 26 unmodified lines | ||
| 1324 | 1324 | * Once the object->lock is acquired, the corresponding memory block |
| 1325 | 1325 | * cannot be freed (the same lock is acquired in delete_object). |
| 1326 | 1326 | */ |
| 1327 | − spin_lock_irqsave(&object->lock, flags); | |
| 1327 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1328 | 1328 | if (object->flags & OBJECT_NO_SCAN) |
| 1329 | 1329 | goto out; |
| 1330 | 1330 | if (!(object->flags & OBJECT_ALLOCATED)) |
| @@ -1344,9 +1344,9 @@ static void scan_object(struct kmemleak_object *object) · 13 unmodified lines | ||
| 1344 | 1344 | if (start >= end) |
| 1345 | 1345 | break; |
| 1346 | 1346 | |
| 1347 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1347 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1348 | 1348 | cond_resched(); |
| 1349 | − spin_lock_irqsave(&object->lock, flags); | |
| 1349 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1350 | 1350 | } while (object->flags & OBJECT_ALLOCATED); |
| 1351 | 1351 | } else |
| 1352 | 1352 | hlist_for_each_entry(area, &object->area_list, node) |
| @@ -1354,7 +1354,7 @@ static void scan_object(struct kmemleak_object *object) · 1 unmodified line | ||
| 1354 | 1354 | (void *)(area->start + area->size), |
| 1355 | 1355 | object); |
| 1356 | 1356 | out: |
| 1357 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1357 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1358 | 1358 | } |
| 1359 | 1359 | |
| 1360 | 1360 | /* |
| @@ -1407,7 +1407,7 @@ static void kmemleak_scan(void) · 46 unmodified lines | ||
| 1407 | 1407 | /* prepare the kmemleak_object's */ |
| 1408 | 1408 | rcu_read_lock(); |
| 1409 | 1409 | list_for_each_entry_rcu(object, &object_list, object_list) { |
| 1410 | − spin_lock_irqsave(&object->lock, flags); | |
| 1410 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1411 | 1411 | #ifdef DEBUG |
| 1412 | 1412 | /* |
| 1413 | 1413 | * With a few exceptions there should be a maximum of |
| @@ -1424,7 +1424,7 @@ static void kmemleak_scan(void) · 10 unmodified lines | ||
| 1424 | 1424 | if (color_gray(object) && get_object(object)) |
| 1425 | 1425 | list_add_tail(&object->gray_list, &gray_list); |
| 1426 | 1426 | |
| 1427 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1427 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1428 | 1428 | } |
| 1429 | 1429 | rcu_read_unlock(); |
| 1430 | 1430 | |
| @@ -1492,14 +1492,14 @@ static void kmemleak_scan(void) · 61 unmodified lines | ||
| 1492 | 1492 | */ |
| 1493 | 1493 | rcu_read_lock(); |
| 1494 | 1494 | list_for_each_entry_rcu(object, &object_list, object_list) { |
| 1495 | − spin_lock_irqsave(&object->lock, flags); | |
| 1495 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1496 | 1496 | if (color_white(object) && (object->flags & OBJECT_ALLOCATED) |
| 1497 | 1497 | && update_checksum(object) && get_object(object)) { |
| 1498 | 1498 | /* color it gray temporarily */ |
| 1499 | 1499 | object->count = object->min_count; |
| 1500 | 1500 | list_add_tail(&object->gray_list, &gray_list); |
| 1501 | 1501 | } |
| 1502 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1502 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1503 | 1503 | } |
| 1504 | 1504 | rcu_read_unlock(); |
| 1505 | 1505 | |
| @@ -1519,7 +1519,7 @@ static void kmemleak_scan(void) · 13 unmodified lines | ||
| 1519 | 1519 | */ |
| 1520 | 1520 | rcu_read_lock(); |
| 1521 | 1521 | list_for_each_entry_rcu(object, &object_list, object_list) { |
| 1522 | − spin_lock_irqsave(&object->lock, flags); | |
| 1522 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1523 | 1523 | if (unreferenced_object(object) && |
| 1524 | 1524 | !(object->flags & OBJECT_REPORTED)) { |
| 1525 | 1525 | object->flags |= OBJECT_REPORTED; |
| @@ -1529,7 +1529,7 @@ static void kmemleak_scan(void) · 3 unmodified lines | ||
| 1529 | 1529 | |
| 1530 | 1530 | new_leaks++; |
| 1531 | 1531 | } |
| 1532 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1532 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1533 | 1533 | } |
| 1534 | 1534 | rcu_read_unlock(); |
| 1535 | 1535 | |
| @@ -1681,10 +1681,10 @@ static int kmemleak_seq_show(struct seq_file *seq, void *v) · 145 unmodified lines | ||
| 1681 | 1681 | struct kmemleak_object *object = v; |
| 1682 | 1682 | unsigned long flags; |
| 1683 | 1683 | |
| 1684 | − spin_lock_irqsave(&object->lock, flags); | |
| 1684 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1685 | 1685 | if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) |
| 1686 | 1686 | print_unreferenced(seq, object); |
| 1687 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1687 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1688 | 1688 | return 0; |
| 1689 | 1689 | } |
| 1690 | 1690 | |
| @@ -1714,9 +1714,9 @@ static int dump_str_object_info(const char *str) · 23 unmodified lines | ||
| 1714 | 1714 | return -EINVAL; |
| 1715 | 1715 | } |
| 1716 | 1716 | |
| 1717 | − spin_lock_irqsave(&object->lock, flags); | |
| 1717 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1718 | 1718 | dump_object_info(object); |
| 1719 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1719 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1720 | 1720 | |
| 1721 | 1721 | put_object(object); |
| 1722 | 1722 | return 0; |
| @@ -1735,11 +1735,11 @@ static void kmemleak_clear(void) · 12 unmodified lines | ||
| 1735 | 1735 | |
| 1736 | 1736 | rcu_read_lock(); |
| 1737 | 1737 | list_for_each_entry_rcu(object, &object_list, object_list) { |
| 1738 | − spin_lock_irqsave(&object->lock, flags); | |
| 1738 | + raw_spin_lock_irqsave(&object->lock, flags); | |
| 1739 | 1739 | if ((object->flags & OBJECT_REPORTED) && |
| 1740 | 1740 | unreferenced_object(object)) |
| 1741 | 1741 | __paint_it(object, KMEMLEAK_GREY); |
| 1742 | − spin_unlock_irqrestore(&object->lock, flags); | |
| 1742 | + raw_spin_unlock_irqrestore(&object->lock, flags); | |
| 1743 | 1743 | } |
| 1744 | 1744 | rcu_read_unlock(); |
| 1745 | 1745 | |
| @@ -575,7 +575,7 @@ static void __init_memblock memblock_insert_region(struct memblock_type *type, · 574 unmodified lines | ||
| 575 | 575 | * Return: |
| 576 | 576 | * 0 on success, -errno on failure. |
| 577 | 577 | */ |
| 578 | −int __init_memblock memblock_add_range(struct memblock_type *type, | |
| 578 | +static int __init_memblock memblock_add_range(struct memblock_type *type, | |
| 579 | 579 | phys_addr_t base, phys_addr_t size, |
| 580 | 580 | int nid, enum memblock_flags flags) |
| 581 | 581 | { |
| @@ -694,7 +694,7 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) · 112 unmodified lines | ||
| 694 | 694 | { |
| 695 | 695 | phys_addr_t end = base + size - 1; |
| 696 | 696 | |
| 697 | − memblock_dbg("memblock_add: [%pa-%pa] %pS\n", | |
| 697 | + memblock_dbg("%s: [%pa-%pa] %pS\n", __func__, | |
| 698 | 698 | &base, &end, (void *)_RET_IP_); |
| 699 | 699 | |
| 700 | 700 | return memblock_add_range(&memblock.memory, base, size, MAX_NUMNODES, 0); |
| @@ -795,7 +795,7 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size) · 94 unmodified lines | ||
| 795 | 795 | { |
| 796 | 796 | phys_addr_t end = base + size - 1; |
| 797 | 797 | |
| 798 | − memblock_dbg("memblock_remove: [%pa-%pa] %pS\n", | |
| 798 | + memblock_dbg("%s: [%pa-%pa] %pS\n", __func__, | |
| 799 | 799 | &base, &end, (void *)_RET_IP_); |
| 800 | 800 | |
| 801 | 801 | return memblock_remove_range(&memblock.memory, base, size); |
| @@ -813,7 +813,7 @@ int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size) · 11 unmodified lines | ||
| 813 | 813 | { |
| 814 | 814 | phys_addr_t end = base + size - 1; |
| 815 | 815 | |
| 816 | − memblock_dbg(" memblock_free: [%pa-%pa] %pS\n", | |
| 816 | + memblock_dbg("%s: [%pa-%pa] %pS\n", __func__, | |
| 817 | 817 | &base, &end, (void *)_RET_IP_); |
| 818 | 818 | |
| 819 | 819 | kmemleak_free_part_phys(base, size); |
| @@ -824,12 +824,24 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) · 4 unmodified lines | ||
| 824 | 824 | { |
| 825 | 825 | phys_addr_t end = base + size - 1; |
| 826 | 826 | |
| 827 | − memblock_dbg("memblock_reserve: [%pa-%pa] %pS\n", | |
| 827 | + memblock_dbg("%s: [%pa-%pa] %pS\n", __func__, | |
| 828 | 828 | &base, &end, (void *)_RET_IP_); |
| 829 | 829 | |
| 830 | 830 | return memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0); |
| 831 | 831 | } |
| 832 | 832 | |
| 833 | +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP | |
| 834 | +int __init_memblock memblock_physmem_add(phys_addr_t base, phys_addr_t size) | |
| 835 | +{ | |
| 836 | + phys_addr_t end = base + size - 1; | |
| 837 | + | |
| 838 | + memblock_dbg("%s: [%pa-%pa] %pS\n", __func__, | |
| 839 | + &base, &end, (void *)_RET_IP_); | |
| 840 | + | |
| 841 | + return memblock_add_range(&memblock.physmem, base, size, MAX_NUMNODES, 0); | |
| 842 | +} | |
| 843 | +#endif | |
| 844 | + | |
| 833 | 845 | /** |
| 834 | 846 | * memblock_setclr_flag - set or clear flag for a memory region |
| 835 | 847 | * @base: base address of the region |
| @@ -5340,14 +5340,6 @@ static int mem_cgroup_move_account(struct page *page, · 5339 unmodified lines | ||
| 5340 | 5340 | __mod_lruvec_state(to_vec, NR_WRITEBACK, nr_pages); |
| 5341 | 5341 | } |
| 5342 | 5342 | |
| 5343 | −#ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
| 5344 | − if (compound && !list_empty(page_deferred_list(page))) { | |
| 5345 | − spin_lock(&from->deferred_split_queue.split_queue_lock); | |
| 5346 | − list_del_init(page_deferred_list(page)); | |
| 5347 | − from->deferred_split_queue.split_queue_len--; | |
| 5348 | − spin_unlock(&from->deferred_split_queue.split_queue_lock); | |
| 5349 | − } | |
| 5350 | −#endif | |
| 5351 | 5343 | /* |
| 5352 | 5344 | * It is safe to change page->mem_cgroup here because the page |
| 5353 | 5345 | * is referenced, charged, and isolated - we can't race with |
| @@ -5357,16 +5349,6 @@ static int mem_cgroup_move_account(struct page *page, · 3 unmodified lines | ||
| 5357 | 5349 | /* caller should have done css_get */ |
| 5358 | 5350 | page->mem_cgroup = to; |
| 5359 | 5351 | |
| 5360 | −#ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
| 5361 | − if (compound && list_empty(page_deferred_list(page))) { | |
| 5362 | − spin_lock(&to->deferred_split_queue.split_queue_lock); | |
| 5363 | − list_add_tail(page_deferred_list(page), | |
| 5364 | − &to->deferred_split_queue.split_queue); | |
| 5365 | − to->deferred_split_queue.split_queue_len++; | |
| 5366 | − spin_unlock(&to->deferred_split_queue.split_queue_lock); | |
| 5367 | − } | |
| 5368 | −#endif | |
| 5369 | − | |
| 5370 | 5352 | spin_unlock_irqrestore(&from->move_lock, flags); |
| 5371 | 5353 | |
| 5372 | 5354 | ret = 0; |
| @@ -6651,7 +6633,6 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage) · 1278 unmodified lines | ||
| 6651 | 6633 | { |
| 6652 | 6634 | struct mem_cgroup *memcg; |
| 6653 | 6635 | unsigned int nr_pages; |
| 6654 | − bool compound; | |
| 6655 | 6636 | unsigned long flags; |
| 6656 | 6637 | |
| 6657 | 6638 | VM_BUG_ON_PAGE(!PageLocked(oldpage), oldpage); |
| @@ -6673,8 +6654,7 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage) · 15 unmodified lines | ||
| 6673 | 6654 | return; |
| 6674 | 6655 | |
| 6675 | 6656 | /* Force-charge the new page. The old one will be freed soon */ |
| 6676 | − compound = PageTransHuge(newpage); | |
| 6677 | − nr_pages = compound ? hpage_nr_pages(newpage) : 1; | |
| 6657 | + nr_pages = hpage_nr_pages(newpage); | |
| 6678 | 6658 | |
| 6679 | 6659 | page_counter_charge(&memcg->memory, nr_pages); |
| 6680 | 6660 | if (do_memsw_account()) |
| @@ -6684,7 +6664,8 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage) · 3 unmodified lines | ||
| 6684 | 6664 | commit_charge(newpage, memcg, false); |
| 6685 | 6665 | |
| 6686 | 6666 | local_irq_save(flags); |
| 6687 | − mem_cgroup_charge_statistics(memcg, newpage, compound, nr_pages); | |
| 6667 | + mem_cgroup_charge_statistics(memcg, newpage, PageTransHuge(newpage), | |
| 6668 | + nr_pages); | |
| 6688 | 6669 | memcg_check_events(memcg, newpage); |
| 6689 | 6670 | local_irq_restore(flags); |
| 6690 | 6671 | } |
| @@ -783,27 +783,18 @@ struct zone * zone_for_pfn_range(int online_type, int nid, unsigned start_pfn, · 782 unmodified lines | ||
| 783 | 783 | return default_zone_for_pfn(nid, start_pfn, nr_pages); |
| 784 | 784 | } |
| 785 | 785 | |
| 786 | −int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_type) | |
| 786 | +int __ref online_pages(unsigned long pfn, unsigned long nr_pages, | |
| 787 | + int online_type, int nid) | |
| 787 | 788 | { |
| 788 | 789 | unsigned long flags; |
| 789 | 790 | unsigned long onlined_pages = 0; |
| 790 | 791 | struct zone *zone; |
| 791 | 792 | int need_zonelists_rebuild = 0; |
| 792 | − int nid; | |
| 793 | 793 | int ret; |
| 794 | 794 | struct memory_notify arg; |
| 795 | − struct memory_block *mem; | |
| 796 | 795 | |
| 797 | 796 | mem_hotplug_begin(); |
| 798 | 797 | |
| 799 | − /* | |
| 800 | − * We can't use pfn_to_nid() because nid might be stored in struct page | |
| 801 | − * which is not yet initialized. Instead, we find nid from memory block. | |
| 802 | − */ | |
| 803 | − mem = find_memory_block(__pfn_to_section(pfn)); | |
| 804 | − nid = mem->nid; | |
| 805 | − put_device(&mem->dev); | |
| 806 | − | |
| 807 | 798 | /* associate pfn range with the zone */ |
| 808 | 799 | zone = zone_for_pfn_range(online_type, nid, pfn, nr_pages); |
| 809 | 800 | move_pfn_range_to_zone(zone, pfn, nr_pages, NULL); |
| @@ -1182,7 +1173,7 @@ static bool is_pageblock_removable_nolock(unsigned long pfn) · 372 unmodified lines | ||
| 1182 | 1173 | if (!zone_spans_pfn(zone, pfn)) |
| 1183 | 1174 | return false; |
| 1184 | 1175 | |
| 1185 | − return !has_unmovable_pages(zone, page, 0, MIGRATE_MOVABLE, | |
| 1176 | + return !has_unmovable_pages(zone, page, MIGRATE_MOVABLE, | |
| 1186 | 1177 | MEMORY_OFFLINE); |
| 1187 | 1178 | } |
| 1188 | 1179 | |
| @@ -1764,8 +1755,6 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size) · 575 unmodified lines | ||
| 1764 | 1755 | |
| 1765 | 1756 | BUG_ON(check_hotplug_memory_range(start, size)); |
| 1766 | 1757 | |
| 1767 | − mem_hotplug_begin(); | |
| 1768 | − | |
| 1769 | 1758 | /* |
| 1770 | 1759 | * All memory blocks must be offlined before removing memory. Check |
| 1771 | 1760 | * whether all memory blocks in question are offline and return error |
| @@ -1778,9 +1767,14 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size) · 6 unmodified lines | ||
| 1778 | 1767 | /* remove memmap entry */ |
| 1779 | 1768 | firmware_map_remove(start, start + size, "System RAM"); |
| 1780 | 1769 | |
| 1781 | − /* remove memory block devices before removing memory */ | |
| 1770 | + /* | |
| 1771 | + * Memory block device removal under the device_hotplug_lock is | |
| 1772 | + * a barrier against racing online attempts. | |
| 1773 | + */ | |
| 1782 | 1774 | remove_memory_block_devices(start, size); |
| 1783 | 1775 | |
| 1776 | + mem_hotplug_begin(); | |
| 1777 | + | |
| 1784 | 1778 | arch_remove_memory(nid, start, size, NULL); |
| 1785 | 1779 | memblock_free(start, size); |
| 1786 | 1780 | memblock_remove(start, size); |
| @@ -2821,6 +2821,9 @@ int mpol_parse_str(char *str, struct mempolicy **mpol) · 2820 unmodified lines | ||
| 2821 | 2821 | char *flags = strchr(str, '='); |
| 2822 | 2822 | int err = 1, mode; |
| 2823 | 2823 | |
| 2824 | + if (flags) | |
| 2825 | + *flags++ = '\0'; /* terminate mode string */ | |
| 2826 | + | |
| 2824 | 2827 | if (nodelist) { |
| 2825 | 2828 | /* NUL-terminate mode or flags string */ |
| 2826 | 2829 | *nodelist++ = '\0'; |
| @@ -2831,9 +2834,6 @@ int mpol_parse_str(char *str, struct mempolicy **mpol) · 4 unmodified lines | ||
| 2831 | 2834 | } else |
| 2832 | 2835 | nodes_clear(nodes); |
| 2833 | 2836 | |
| 2834 | − if (flags) | |
| 2835 | − *flags++ = '\0'; /* terminate mode string */ | |
| 2836 | − | |
| 2837 | 2837 | mode = match_string(policy_modes, MPOL_MAX, str); |
| 2838 | 2838 | if (mode < 0) |
| 2839 | 2839 | goto out; |
| @@ -27,7 +27,8 @@ static void devmap_managed_enable_put(void) · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | static int devmap_managed_enable_get(struct dev_pagemap *pgmap) |
| 29 | 29 | { |
| 30 | − if (!pgmap->ops || !pgmap->ops->page_free) { | |
| 30 | + if (pgmap->type == MEMORY_DEVICE_PRIVATE && | |
| 31 | + (!pgmap->ops || !pgmap->ops->page_free)) { | |
| 31 | 32 | WARN(1, "Missing page_free method\n"); |
| 32 | 33 | return -EINVAL; |
| 33 | 34 | } |
| @@ -410,48 +411,42 @@ struct dev_pagemap *get_dev_pagemap(unsigned long pfn, · 376 unmodified lines | ||
| 410 | 411 | EXPORT_SYMBOL_GPL(get_dev_pagemap); |
| 411 | 412 | |
| 412 | 413 | #ifdef CONFIG_DEV_PAGEMAP_OPS |
| 413 | −void __put_devmap_managed_page(struct page *page) | |
| 414 | +void free_devmap_managed_page(struct page *page) | |
| 414 | 415 | { |
| 415 | − int count = page_ref_dec_return(page); | |
| 416 | − | |
| 417 | − /* | |
| 418 | − * If refcount is 1 then page is freed and refcount is stable as nobody | |
| 419 | − * holds a reference on the page. | |
| 420 | − */ | |
| 421 | − if (count == 1) { | |
| 422 | − /* Clear Active bit in case of parallel mark_page_accessed */ | |
| 423 | − __ClearPageActive(page); | |
| 424 | − __ClearPageWaiters(page); | |
| 416 | + /* notify page idle for dax */ | |
| 417 | + if (!is_device_private_page(page)) { | |
| 418 | + wake_up_var(&page->_refcount); | |
| 419 | + return; | |
| 420 | + } | |
| 425 | 421 | |
| 426 | − mem_cgroup_uncharge(page); | |
| 422 | + /* Clear Active bit in case of parallel mark_page_accessed */ | |
| 423 | + __ClearPageActive(page); | |
| 424 | + __ClearPageWaiters(page); | |
| 427 | 425 | |
| 428 | − /* | |
| 429 | − * When a device_private page is freed, the page->mapping field | |
| 430 | − * may still contain a (stale) mapping value. For example, the | |
| 431 | − * lower bits of page->mapping may still identify the page as | |
| 432 | − * an anonymous page. Ultimately, this entire field is just | |
| 433 | − * stale and wrong, and it will cause errors if not cleared. | |
| 434 | − * One example is: | |
| 435 | − * | |
| 436 | − * migrate_vma_pages() | |
| 437 | − * migrate_vma_insert_page() | |
| 438 | − * page_add_new_anon_rmap() | |
| 439 | − * __page_set_anon_rmap() | |
| 440 | − * ...checks page->mapping, via PageAnon(page) call, | |
| 441 | − * and incorrectly concludes that the page is an | |
| 442 | − * anonymous page. Therefore, it incorrectly, | |
| 443 | − * silently fails to set up the new anon rmap. | |
| 444 | − * | |
| 445 | − * For other types of ZONE_DEVICE pages, migration is either | |
| 446 | − * handled differently or not done at all, so there is no need | |
| 447 | − * to clear page->mapping. | |
| 448 | − */ | |
| 449 | − if (is_device_private_page(page)) | |
| 450 | − page->mapping = NULL; | |
| 426 | + mem_cgroup_uncharge(page); | |
| 451 | 427 | |
| 452 | − page->pgmap->ops->page_free(page); | |
| 453 | − } else if (!count) | |
| 454 | − __put_page(page); | |
| 428 | + /* | |
| 429 | + * When a device_private page is freed, the page->mapping field | |
| 430 | + * may still contain a (stale) mapping value. For example, the | |
| 431 | + * lower bits of page->mapping may still identify the page as an | |
| 432 | + * anonymous page. Ultimately, this entire field is just stale | |
| 433 | + * and wrong, and it will cause errors if not cleared. One | |
| 434 | + * example is: | |
| 435 | + * | |
| 436 | + * migrate_vma_pages() | |
| 437 | + * migrate_vma_insert_page() | |
| 438 | + * page_add_new_anon_rmap() | |
| 439 | + * __page_set_anon_rmap() | |
| 440 | + * ...checks page->mapping, via PageAnon(page) call, | |
| 441 | + * and incorrectly concludes that the page is an | |
| 442 | + * anonymous page. Therefore, it incorrectly, | |
| 443 | + * silently fails to set up the new anon rmap. | |
| 444 | + * | |
| 445 | + * For other types of ZONE_DEVICE pages, migration is either | |
| 446 | + * handled differently or not done at all, so there is no need | |
| 447 | + * to clear page->mapping. | |
| 448 | + */ | |
| 449 | + page->mapping = NULL; | |
| 450 | + page->pgmap->ops->page_free(page); | |
| 455 | 451 | } |
| 456 | −EXPORT_SYMBOL(__put_devmap_managed_page); | |
| 457 | 452 | #endif /* CONFIG_DEV_PAGEMAP_OPS */ |
| @@ -48,6 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | #include <linux/page_owner.h> |
| 49 | 49 | #include <linux/sched/mm.h> |
| 50 | 50 | #include <linux/ptrace.h> |
| 51 | +#include <linux/oom.h> | |
| 51 | 52 | |
| 52 | 53 | #include <asm/tlbflush.h> |
| 53 | 54 | |
| @@ -986,7 +987,7 @@ static int move_to_new_page(struct page *newpage, struct page *page, · 932 unmodified lines | ||
| 986 | 987 | } |
| 987 | 988 | |
| 988 | 989 | /* |
| 989 | − * Anonymous and movable page->mapping will be cleard by | |
| 990 | + * Anonymous and movable page->mapping will be cleared by | |
| 990 | 991 | * free_pages_prepare so don't reset it here for keeping |
| 991 | 992 | * the type to work PageAnon, for example. |
| 992 | 993 | */ |
| @@ -1199,8 +1200,7 @@ out: · 206 unmodified lines | ||
| 1199 | 1200 | /* |
| 1200 | 1201 | * A page that has been migrated has all references |
| 1201 | 1202 | * removed and will be freed. A page that has not been |
| 1202 | − * migrated will have kepts its references and be | |
| 1203 | − * restored. | |
| 1203 | + * migrated will have kept its references and be restored. | |
| 1204 | 1204 | */ |
| 1205 | 1205 | list_del(&page->lru); |
| 1206 | 1206 | |
| @@ -1627,8 +1627,19 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, · 420 unmodified lines | ||
| 1627 | 1627 | start = i; |
| 1628 | 1628 | } else if (node != current_node) { |
| 1629 | 1629 | err = do_move_pages_to_node(mm, &pagelist, current_node); |
| 1630 | − if (err) | |
| 1630 | + if (err) { | |
| 1631 | + /* | |
| 1632 | + * Positive err means the number of failed | |
| 1633 | + * pages to migrate. Since we are going to | |
| 1634 | + * abort and return the number of non-migrated | |
| 1635 | + * pages, so need to incude the rest of the | |
| 1636 | + * nr_pages that have not been attempted as | |
| 1637 | + * well. | |
| 1638 | + */ | |
| 1639 | + if (err > 0) | |
| 1640 | + err += nr_pages - i - 1; | |
| 1631 | 1641 | goto out; |
| 1642 | + } | |
| 1632 | 1643 | err = store_status(status, start, current_node, i - start); |
| 1633 | 1644 | if (err) |
| 1634 | 1645 | goto out; |
| @@ -1659,8 +1670,11 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, · 24 unmodified lines | ||
| 1659 | 1670 | goto out_flush; |
| 1660 | 1671 | |
| 1661 | 1672 | err = do_move_pages_to_node(mm, &pagelist, current_node); |
| 1662 | − if (err) | |
| 1673 | + if (err) { | |
| 1674 | + if (err > 0) | |
| 1675 | + err += nr_pages - i - 1; | |
| 1663 | 1676 | goto out; |
| 1677 | + } | |
| 1664 | 1678 | if (i > start) { |
| 1665 | 1679 | err = store_status(status, start, current_node, i - start); |
| 1666 | 1680 | if (err) |
| @@ -1674,9 +1688,16 @@ out_flush: · 7 unmodified lines | ||
| 1674 | 1688 | |
| 1675 | 1689 | /* Make sure we do not overwrite the existing error */ |
| 1676 | 1690 | err1 = do_move_pages_to_node(mm, &pagelist, current_node); |
| 1691 | + /* | |
| 1692 | + * Don't have to report non-attempted pages here since: | |
| 1693 | + * - If the above loop is done gracefully all pages have been | |
| 1694 | + * attempted. | |
| 1695 | + * - If the above loop is aborted it means a fatal error | |
| 1696 | + * happened, should return ret. | |
| 1697 | + */ | |
| 1677 | 1698 | if (!err1) |
| 1678 | 1699 | err1 = store_status(status, start, current_node, i - start); |
| 1679 | − if (!err) | |
| 1700 | + if (err >= 0) | |
| 1680 | 1701 | err = err1; |
| 1681 | 1702 | out: |
| 1682 | 1703 | return err; |
| @@ -2135,7 +2156,7 @@ static int migrate_vma_collect_hole(unsigned long start, · 452 unmodified lines | ||
| 2135 | 2156 | struct migrate_vma *migrate = walk->private; |
| 2136 | 2157 | unsigned long addr; |
| 2137 | 2158 | |
| 2138 | − for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) { | |
| 2159 | + for (addr = start; addr < end; addr += PAGE_SIZE) { | |
| 2139 | 2160 | migrate->src[migrate->npages] = MIGRATE_PFN_MIGRATE; |
| 2140 | 2161 | migrate->dst[migrate->npages] = 0; |
| 2141 | 2162 | migrate->npages++; |
| @@ -2152,7 +2173,7 @@ static int migrate_vma_collect_skip(unsigned long start, · 10 unmodified lines | ||
| 2152 | 2173 | struct migrate_vma *migrate = walk->private; |
| 2153 | 2174 | unsigned long addr; |
| 2154 | 2175 | |
| 2155 | − for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) { | |
| 2176 | + for (addr = start; addr < end; addr += PAGE_SIZE) { | |
| 2156 | 2177 | migrate->dst[migrate->npages] = 0; |
| 2157 | 2178 | migrate->src[migrate->npages++] = 0; |
| 2158 | 2179 | } |
| @@ -2675,6 +2696,14 @@ int migrate_vma_setup(struct migrate_vma *args) · 516 unmodified lines | ||
| 2675 | 2696 | } |
| 2676 | 2697 | EXPORT_SYMBOL(migrate_vma_setup); |
| 2677 | 2698 | |
| 2699 | +/* | |
| 2700 | + * This code closely matches the code in: | |
| 2701 | + * __handle_mm_fault() | |
| 2702 | + * handle_pte_fault() | |
| 2703 | + * do_anonymous_page() | |
| 2704 | + * to map in an anonymous zero page but the struct page will be a ZONE_DEVICE | |
| 2705 | + * private page. | |
| 2706 | + */ | |
| 2678 | 2707 | static void migrate_vma_insert_page(struct migrate_vma *migrate, |
| 2679 | 2708 | unsigned long addr, |
| 2680 | 2709 | struct page *page, |
| @@ -2755,30 +2784,24 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate, · 74 unmodified lines | ||
| 2755 | 2784 | |
| 2756 | 2785 | ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl); |
| 2757 | 2786 | |
| 2787 | + if (check_stable_address_space(mm)) | |
| 2788 | + goto unlock_abort; | |
| 2789 | + | |
| 2758 | 2790 | if (pte_present(*ptep)) { |
| 2759 | 2791 | unsigned long pfn = pte_pfn(*ptep); |
| 2760 | 2792 | |
| 2761 | − if (!is_zero_pfn(pfn)) { | |
| 2762 | − pte_unmap_unlock(ptep, ptl); | |
| 2763 | − mem_cgroup_cancel_charge(page, memcg, false); | |
| 2764 | − goto abort; | |
| 2765 | − } | |
| 2793 | + if (!is_zero_pfn(pfn)) | |
| 2794 | + goto unlock_abort; | |
| 2766 | 2795 | flush = true; |
| 2767 | − } else if (!pte_none(*ptep)) { | |
| 2768 | − pte_unmap_unlock(ptep, ptl); | |
| 2769 | − mem_cgroup_cancel_charge(page, memcg, false); | |
| 2770 | − goto abort; | |
| 2771 | − } | |
| 2796 | + } else if (!pte_none(*ptep)) | |
| 2797 | + goto unlock_abort; | |
| 2772 | 2798 | |
| 2773 | 2799 | /* |
| 2774 | − * Check for usefaultfd but do not deliver the fault. Instead, | |
| 2800 | + * Check for userfaultfd but do not deliver the fault. Instead, | |
| 2775 | 2801 | * just back off. |
| 2776 | 2802 | */ |
| 2777 | − if (userfaultfd_missing(vma)) { | |
| 2778 | − pte_unmap_unlock(ptep, ptl); | |
| 2779 | − mem_cgroup_cancel_charge(page, memcg, false); | |
| 2780 | − goto abort; | |
| 2781 | − } | |
| 2803 | + if (userfaultfd_missing(vma)) | |
| 2804 | + goto unlock_abort; | |
| 2782 | 2805 | |
| 2783 | 2806 | inc_mm_counter(mm, MM_ANONPAGES); |
| 2784 | 2807 | page_add_new_anon_rmap(page, vma, addr, false); |
| @@ -2802,6 +2825,9 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate, · 17 unmodified lines | ||
| 2802 | 2825 | *src = MIGRATE_PFN_MIGRATE; |
| 2803 | 2826 | return; |
| 2804 | 2827 | |
| 2828 | +unlock_abort: | |
| 2829 | + pte_unmap_unlock(ptep, ptl); | |
| 2830 | + mem_cgroup_cancel_charge(page, memcg, false); | |
| 2805 | 2831 | abort: |
| 2806 | 2832 | *src &= ~MIGRATE_PFN_MIGRATE; |
| 2807 | 2833 | } |
| @@ -2834,9 +2860,8 @@ void migrate_vma_pages(struct migrate_vma *migrate) · 26 unmodified lines | ||
| 2834 | 2860 | } |
| 2835 | 2861 | |
| 2836 | 2862 | if (!page) { |
| 2837 | − if (!(migrate->src[i] & MIGRATE_PFN_MIGRATE)) { | |
| 2863 | + if (!(migrate->src[i] & MIGRATE_PFN_MIGRATE)) | |
| 2838 | 2864 | continue; |
| 2839 | − } | |
| 2840 | 2865 | if (!notified) { |
| 2841 | 2866 | notified = true; |
| 2842 | 2867 | |
| @@ -1270,26 +1270,22 @@ static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_ · 1269 unmodified lines | ||
| 1270 | 1270 | */ |
| 1271 | 1271 | struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma) |
| 1272 | 1272 | { |
| 1273 | − struct anon_vma *anon_vma; | |
| 1274 | − struct vm_area_struct *near; | |
| 1275 | − | |
| 1276 | − near = vma->vm_next; | |
| 1277 | − if (!near) | |
| 1278 | − goto try_prev; | |
| 1279 | − | |
| 1280 | − anon_vma = reusable_anon_vma(near, vma, near); | |
| 1281 | − if (anon_vma) | |
| 1282 | − return anon_vma; | |
| 1283 | −try_prev: | |
| 1284 | − near = vma->vm_prev; | |
| 1285 | − if (!near) | |
| 1286 | − goto none; | |
| 1287 | − | |
| 1288 | − anon_vma = reusable_anon_vma(near, near, vma); | |
| 1289 | − if (anon_vma) | |
| 1290 | − return anon_vma; | |
| 1291 | −none: | |
| 1273 | + struct anon_vma *anon_vma = NULL; | |
| 1274 | + | |
| 1275 | + /* Try next first. */ | |
| 1276 | + if (vma->vm_next) { | |
| 1277 | + anon_vma = reusable_anon_vma(vma->vm_next, vma, vma->vm_next); | |
| 1278 | + if (anon_vma) | |
| 1279 | + return anon_vma; | |
| 1280 | + } | |
| 1281 | + | |
| 1282 | + /* Try prev next. */ | |
| 1283 | + if (vma->vm_prev) | |
| 1284 | + anon_vma = reusable_anon_vma(vma->vm_prev, vma->vm_prev, vma); | |
| 1285 | + | |
| 1292 | 1286 | /* |
| 1287 | + * We might reach here with anon_vma == NULL if we can't find | |
| 1288 | + * any reusable anon_vma. | |
| 1293 | 1289 | * There's no absolute need to look only at touching neighbours: |
| 1294 | 1290 | * we could search further afield for "compatible" anon_vmas. |
| 1295 | 1291 | * But it would probably just be a waste of time searching, |
| @@ -1297,7 +1293,7 @@ none: · 1 unmodified line | ||
| 1297 | 1293 | * We're trying to allow mprotect remerging later on, |
| 1298 | 1294 | * not trying to minimize memory used for anon_vmas. |
| 1299 | 1295 | */ |
| 1300 | − return NULL; | |
| 1296 | + return anon_vma; | |
| 1301 | 1297 | } |
| 1302 | 1298 | |
| 1303 | 1299 | /* |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/sched/mm.h> |
| 27 | 27 | #include <linux/sched/coredump.h> |
| 28 | 28 | #include <linux/sched/task.h> |
| 29 | +#include <linux/sched/debug.h> | |
| 29 | 30 | #include <linux/swap.h> |
| 30 | 31 | #include <linux/timex.h> |
| 31 | 32 | #include <linux/jiffies.h> |
| @@ -620,6 +621,7 @@ static void oom_reap_task(struct task_struct *tsk) · 588 unmodified lines | ||
| 620 | 621 | |
| 621 | 622 | pr_info("oom_reaper: unable to reap pid:%d (%s)\n", |
| 622 | 623 | task_pid_nr(tsk), tsk->comm); |
| 624 | + sched_show_task(tsk); | |
| 623 | 625 | debug_show_all_locks(); |
| 624 | 626 | |
| 625 | 627 | done: |
| @@ -5848,6 +5848,30 @@ overlap_memmap_init(unsigned long zone, unsigned long *pfn) · 5847 unmodified lines | ||
| 5848 | 5848 | return false; |
| 5849 | 5849 | } |
| 5850 | 5850 | |
| 5851 | +#ifdef CONFIG_SPARSEMEM | |
| 5852 | +/* Skip PFNs that belong to non-present sections */ | |
| 5853 | +static inline __meminit unsigned long next_pfn(unsigned long pfn) | |
| 5854 | +{ | |
| 5855 | + unsigned long section_nr; | |
| 5856 | + | |
| 5857 | + section_nr = pfn_to_section_nr(++pfn); | |
| 5858 | + if (present_section_nr(section_nr)) | |
| 5859 | + return pfn; | |
| 5860 | + | |
| 5861 | + while (++section_nr <= __highest_present_section_nr) { | |
| 5862 | + if (present_section_nr(section_nr)) | |
| 5863 | + return section_nr_to_pfn(section_nr); | |
| 5864 | + } | |
| 5865 | + | |
| 5866 | + return -1; | |
| 5867 | +} | |
| 5868 | +#else | |
| 5869 | +static inline __meminit unsigned long next_pfn(unsigned long pfn) | |
| 5870 | +{ | |
| 5871 | + return pfn++; | |
| 5872 | +} | |
| 5873 | +#endif | |
| 5874 | + | |
| 5851 | 5875 | /* |
| 5852 | 5876 | * Initially all pages are reserved - free ones are freed |
| 5853 | 5877 | * up by memblock_free_all() once the early boot process is |
| @@ -5887,8 +5911,10 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, · 33 unmodified lines | ||
| 5887 | 5911 | * function. They do not exist on hotplugged memory. |
| 5888 | 5912 | */ |
| 5889 | 5913 | if (context == MEMMAP_EARLY) { |
| 5890 | − if (!early_pfn_valid(pfn)) | |
| 5914 | + if (!early_pfn_valid(pfn)) { | |
| 5915 | + pfn = next_pfn(pfn) - 1; | |
| 5891 | 5916 | continue; |
| 5917 | + } | |
| 5892 | 5918 | if (!early_pfn_in_nid(pfn, nid)) |
| 5893 | 5919 | continue; |
| 5894 | 5920 | if (overlap_memmap_init(zone, &pfn)) |
| @@ -8154,20 +8180,22 @@ void *__init alloc_large_system_hash(const char *tablename, · 2259 unmodified lines | ||
| 8154 | 8180 | |
| 8155 | 8181 | /* |
| 8156 | 8182 | * This function checks whether pageblock includes unmovable pages or not. |
| 8157 | − * If @count is not zero, it is okay to include less @count unmovable pages | |
| 8158 | 8183 | * |
| 8159 | 8184 | * PageLRU check without isolation or lru_lock could race so that |
| 8160 | 8185 | * MIGRATE_MOVABLE block might include unmovable pages. And __PageMovable |
| 8161 | 8186 | * check without lock_page also may miss some movable non-lru pages at |
| 8162 | 8187 | * race condition. So you can't expect this function should be exact. |
| 8188 | + * | |
| 8189 | + * Returns a page without holding a reference. If the caller wants to | |
| 8190 | + * dereference that page (e.g., dumping), it has to make sure that that it | |
| 8191 | + * cannot get removed (e.g., via memory unplug) concurrently. | |
| 8192 | + * | |
| 8163 | 8193 | */ |
| 8164 | −bool has_unmovable_pages(struct zone *zone, struct page *page, int count, | |
| 8165 | − int migratetype, int flags) | |
| 8194 | +struct page *has_unmovable_pages(struct zone *zone, struct page *page, | |
| 8195 | + int migratetype, int flags) | |
| 8166 | 8196 | { |
| 8167 | − unsigned long found; | |
| 8168 | 8197 | unsigned long iter = 0; |
| 8169 | 8198 | unsigned long pfn = page_to_pfn(page); |
| 8170 | − const char *reason = "unmovable page"; | |
| 8171 | 8199 | |
| 8172 | 8200 | /* |
| 8173 | 8201 | * TODO we could make this much more efficient by not checking every |
| @@ -8184,22 +8212,19 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count, · 10 unmodified lines | ||
| 8184 | 8212 | * so consider them movable here. |
| 8185 | 8213 | */ |
| 8186 | 8214 | if (is_migrate_cma(migratetype)) |
| 8187 | − return false; | |
| 8215 | + return NULL; | |
| 8188 | 8216 | |
| 8189 | − reason = "CMA page"; | |
| 8190 | − goto unmovable; | |
| 8217 | + return page; | |
| 8191 | 8218 | } |
| 8192 | 8219 | |
| 8193 | − for (found = 0; iter < pageblock_nr_pages; iter++) { | |
| 8194 | − unsigned long check = pfn + iter; | |
| 8195 | − | |
| 8196 | − if (!pfn_valid_within(check)) | |
| 8220 | + for (; iter < pageblock_nr_pages; iter++) { | |
| 8221 | + if (!pfn_valid_within(pfn + iter)) | |
| 8197 | 8222 | continue; |
| 8198 | 8223 | |
| 8199 | − page = pfn_to_page(check); | |
| 8224 | + page = pfn_to_page(pfn + iter); | |
| 8200 | 8225 | |
| 8201 | 8226 | if (PageReserved(page)) |
| 8202 | − goto unmovable; | |
| 8227 | + return page; | |
| 8203 | 8228 | |
| 8204 | 8229 | /* |
| 8205 | 8230 | * If the zone is movable and we have ruled out all reserved |
| @@ -8219,7 +8244,7 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count, · 13 unmodified lines | ||
| 8219 | 8244 | unsigned int skip_pages; |
| 8220 | 8245 | |
| 8221 | 8246 | if (!hugepage_migration_supported(page_hstate(head))) |
| 8222 | − goto unmovable; | |
| 8247 | + return page; | |
| 8223 | 8248 | |
| 8224 | 8249 | skip_pages = compound_nr(head) - (page - head); |
| 8225 | 8250 | iter += skip_pages - 1; |
| @@ -8245,11 +8270,9 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count, · 19 unmodified lines | ||
| 8245 | 8270 | if ((flags & MEMORY_OFFLINE) && PageHWPoison(page)) |
| 8246 | 8271 | continue; |
| 8247 | 8272 | |
| 8248 | − if (__PageMovable(page)) | |
| 8273 | + if (__PageMovable(page) || PageLRU(page)) | |
| 8249 | 8274 | continue; |
| 8250 | 8275 | |
| 8251 | − if (!PageLRU(page)) | |
| 8252 | − found++; | |
| 8253 | 8276 | /* |
| 8254 | 8277 | * If there are RECLAIMABLE pages, we need to check |
| 8255 | 8278 | * it. But now, memory offline itself doesn't call |
| @@ -8263,15 +8286,9 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count, · 7 unmodified lines | ||
| 8263 | 8286 | * is set to both of a memory hole page and a _used_ kernel |
| 8264 | 8287 | * page at boot. |
| 8265 | 8288 | */ |
| 8266 | − if (found > count) | |
| 8267 | − goto unmovable; | |
| 8289 | + return page; | |
| 8268 | 8290 | } |
| 8269 | − return false; | |
| 8270 | −unmovable: | |
| 8271 | − WARN_ON_ONCE(zone_idx(zone) == ZONE_MOVABLE); | |
| 8272 | − if (flags & REPORT_FAILURE) | |
| 8273 | − dump_page(pfn_to_page(pfn + iter), reason); | |
| 8274 | − return true; | |
| 8291 | + return NULL; | |
| 8275 | 8292 | } |
| 8276 | 8293 | |
| 8277 | 8294 | #ifdef CONFIG_CONTIG_ALLOC |
| @@ -8675,10 +8692,6 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) · 397 unmodified lines | ||
| 8675 | 8692 | BUG_ON(!PageBuddy(page)); |
| 8676 | 8693 | order = page_order(page); |
| 8677 | 8694 | offlined_pages += 1 << order; |
| 8678 | −#ifdef CONFIG_DEBUG_VM | |
| 8679 | − pr_info("remove from free list %lx %d %lx\n", | |
| 8680 | − pfn, 1 << order, end_pfn); | |
| 8681 | −#endif | |
| 8682 | 8695 | del_page_from_free_area(page, &zone->free_area[order]); |
| 8683 | 8696 | pfn += (1 << order); |
| 8684 | 8697 | } |
| @@ -17,10 +17,9 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | static int set_migratetype_isolate(struct page *page, int migratetype, int isol_flags) |
| 19 | 19 | { |
| 20 | + struct page *unmovable = NULL; | |
| 20 | 21 | struct zone *zone; |
| 21 | − unsigned long flags, pfn; | |
| 22 | − struct memory_isolate_notify arg; | |
| 23 | − int notifier_ret; | |
| 22 | + unsigned long flags; | |
| 24 | 23 | int ret = -EBUSY; |
| 25 | 24 | |
| 26 | 25 | zone = page_zone(page); |
| @@ -35,41 +34,12 @@ static int set_migratetype_isolate(struct page *page, int migratetype, int isol_ · 8 unmodified lines | ||
| 35 | 34 | if (is_migrate_isolate_page(page)) |
| 36 | 35 | goto out; |
| 37 | 36 | |
| 38 | − pfn = page_to_pfn(page); | |
| 39 | − arg.start_pfn = pfn; | |
| 40 | − arg.nr_pages = pageblock_nr_pages; | |
| 41 | − arg.pages_found = 0; | |
| 42 | − | |
| 43 | − /* | |
| 44 | − * It may be possible to isolate a pageblock even if the | |
| 45 | − * migratetype is not MIGRATE_MOVABLE. The memory isolation | |
| 46 | − * notifier chain is used by balloon drivers to return the | |
| 47 | − * number of pages in a range that are held by the balloon | |
| 48 | − * driver to shrink memory. If all the pages are accounted for | |
| 49 | − * by balloons, are free, or on the LRU, isolation can continue. | |
| 50 | − * Later, for example, when memory hotplug notifier runs, these | |
| 51 | − * pages reported as "can be isolated" should be isolated(freed) | |
| 52 | − * by the balloon driver through the memory notifier chain. | |
| 53 | − */ | |
| 54 | − notifier_ret = memory_isolate_notify(MEM_ISOLATE_COUNT, &arg); | |
| 55 | − notifier_ret = notifier_to_errno(notifier_ret); | |
| 56 | − if (notifier_ret) | |
| 57 | − goto out; | |
| 58 | 37 | /* |
| 59 | 38 | * FIXME: Now, memory hotplug doesn't call shrink_slab() by itself. |
| 60 | 39 | * We just check MOVABLE pages. |
| 61 | 40 | */ |
| 62 | − if (!has_unmovable_pages(zone, page, arg.pages_found, migratetype, | |
| 63 | − isol_flags)) | |
| 64 | − ret = 0; | |
| 65 | − | |
| 66 | − /* | |
| 67 | − * immobile means "not-on-lru" pages. If immobile is larger than | |
| 68 | − * removable-by-driver pages reported by notifier, we'll fail. | |
| 69 | − */ | |
| 70 | − | |
| 71 | −out: | |
| 72 | − if (!ret) { | |
| 41 | + unmovable = has_unmovable_pages(zone, page, migratetype, isol_flags); | |
| 42 | + if (!unmovable) { | |
| 73 | 43 | unsigned long nr_pages; |
| 74 | 44 | int mt = get_pageblock_migratetype(page); |
| 75 | 45 | |
| @@ -79,11 +49,24 @@ out: · 3 unmodified lines | ||
| 79 | 49 | NULL); |
| 80 | 50 | |
| 81 | 51 | __mod_zone_freepage_state(zone, -nr_pages, mt); |
| 52 | + ret = 0; | |
| 82 | 53 | } |
| 83 | 54 | |
| 55 | +out: | |
| 84 | 56 | spin_unlock_irqrestore(&zone->lock, flags); |
| 85 | − if (!ret) | |
| 57 | + if (!ret) { | |
| 86 | 58 | drain_all_pages(zone); |
| 59 | + } else { | |
| 60 | + WARN_ON_ONCE(zone_idx(zone) == ZONE_MOVABLE); | |
| 61 | + | |
| 62 | + if ((isol_flags & REPORT_FAILURE) && unmovable) | |
| 63 | + /* | |
| 64 | + * printk() with zone->lock held will likely trigger a | |
| 65 | + * lockdep splat, so defer it here. | |
| 66 | + */ | |
| 67 | + dump_page(unmovable, "unmovable page"); | |
| 68 | + } | |
| 69 | + | |
| 87 | 70 | return ret; |
| 88 | 71 | } |
| 89 | 72 | |
| @@ -52,12 +52,16 @@ static bool map_pte(struct page_vma_mapped_walk *pvmw) · 51 unmodified lines | ||
| 52 | 52 | return true; |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | −static inline bool pfn_in_hpage(struct page *hpage, unsigned long pfn) | |
| 55 | +static inline bool pfn_is_match(struct page *page, unsigned long pfn) | |
| 56 | 56 | { |
| 57 | − unsigned long hpage_pfn = page_to_pfn(hpage); | |
| 57 | + unsigned long page_pfn = page_to_pfn(page); | |
| 58 | + | |
| 59 | + /* normal page and hugetlbfs page */ | |
| 60 | + if (!PageTransCompound(page) || PageHuge(page)) | |
| 61 | + return page_pfn == pfn; | |
| 58 | 62 | |
| 59 | 63 | /* THP can be referenced by any subpage */ |
| 60 | − return pfn >= hpage_pfn && pfn - hpage_pfn < hpage_nr_pages(hpage); | |
| 64 | + return pfn >= page_pfn && pfn - page_pfn < hpage_nr_pages(page); | |
| 61 | 65 | } |
| 62 | 66 | |
| 63 | 67 | /** |
| @@ -108,7 +112,7 @@ static bool check_pte(struct page_vma_mapped_walk *pvmw) · 44 unmodified lines | ||
| 108 | 112 | pfn = pte_pfn(*pvmw->pte); |
| 109 | 113 | } |
| 110 | 114 | |
| 111 | − return pfn_in_hpage(pvmw->page, pfn); | |
| 115 | + return pfn_is_match(pvmw->page, pfn); | |
| 112 | 116 | } |
| 113 | 117 | |
| 114 | 118 | /** |
| @@ -42,12 +42,11 @@ static int process_vm_rw_pages(struct page **pages, · 41 unmodified lines | ||
| 42 | 42 | if (copy > len) |
| 43 | 43 | copy = len; |
| 44 | 44 | |
| 45 | − if (vm_write) { | |
| 45 | + if (vm_write) | |
| 46 | 46 | copied = copy_page_from_iter(page, offset, copy, iter); |
| 47 | − set_page_dirty_lock(page); | |
| 48 | − } else { | |
| 47 | + else | |
| 49 | 48 | copied = copy_page_to_iter(page, offset, copy, iter); |
| 50 | − } | |
| 49 | + | |
| 51 | 50 | len -= copied; |
| 52 | 51 | if (copied < copy && iov_iter_count(iter)) |
| 53 | 52 | return -EFAULT; |
| @@ -96,7 +95,7 @@ static int process_vm_rw_single_vec(unsigned long addr, · 42 unmodified lines | ||
| 96 | 95 | flags |= FOLL_WRITE; |
| 97 | 96 | |
| 98 | 97 | while (!rc && nr_pages && iov_iter_count(iter)) { |
| 99 | − int pages = min(nr_pages, max_pages_per_loop); | |
| 98 | + int pinned_pages = min(nr_pages, max_pages_per_loop); | |
| 100 | 99 | int locked = 1; |
| 101 | 100 | size_t bytes; |
| 102 | 101 | |
| @@ -106,14 +105,15 @@ static int process_vm_rw_single_vec(unsigned long addr, · 3 unmodified lines | ||
| 106 | 105 | * current/current->mm |
| 107 | 106 | */ |
| 108 | 107 | down_read(&mm->mmap_sem); |
| 109 | − pages = get_user_pages_remote(task, mm, pa, pages, flags, | |
| 110 | − process_pages, NULL, &locked); | |
| 108 | + pinned_pages = pin_user_pages_remote(task, mm, pa, pinned_pages, | |
| 109 | + flags, process_pages, | |
| 110 | + NULL, &locked); | |
| 111 | 111 | if (locked) |
| 112 | 112 | up_read(&mm->mmap_sem); |
| 113 | − if (pages <= 0) | |
| 113 | + if (pinned_pages <= 0) | |
| 114 | 114 | return -EFAULT; |
| 115 | 115 | |
| 116 | − bytes = pages * PAGE_SIZE - start_offset; | |
| 116 | + bytes = pinned_pages * PAGE_SIZE - start_offset; | |
| 117 | 117 | if (bytes > len) |
| 118 | 118 | bytes = len; |
| 119 | 119 | |
| @@ -122,10 +122,12 @@ static int process_vm_rw_single_vec(unsigned long addr, · 2 unmodified lines | ||
| 122 | 122 | vm_write); |
| 123 | 123 | len -= bytes; |
| 124 | 124 | start_offset = 0; |
| 125 | − nr_pages -= pages; | |
| 126 | − pa += pages * PAGE_SIZE; | |
| 127 | − while (pages) | |
| 128 | − put_page(process_pages[--pages]); | |
| 125 | + nr_pages -= pinned_pages; | |
| 126 | + pa += pinned_pages * PAGE_SIZE; | |
| 127 | + | |
| 128 | + /* If vm_write is set, the pages need to be made dirty: */ | |
| 129 | + unpin_user_pages_dirty_lock(process_pages, pinned_pages, | |
| 130 | + vm_write); | |
| 129 | 131 | } |
| 130 | 132 | |
| 131 | 133 | return rc; |
| @@ -439,19 +439,38 @@ static inline bool cmpxchg_double_slab(struct kmem_cache *s, struct page *page, · 438 unmodified lines | ||
| 439 | 439 | } |
| 440 | 440 | |
| 441 | 441 | #ifdef CONFIG_SLUB_DEBUG |
| 442 | +static unsigned long object_map[BITS_TO_LONGS(MAX_OBJS_PER_PAGE)]; | |
| 443 | +static DEFINE_SPINLOCK(object_map_lock); | |
| 444 | + | |
| 442 | 445 | /* |
| 443 | 446 | * Determine a map of object in use on a page. |
| 444 | 447 | * |
| 445 | 448 | * Node listlock must be held to guarantee that the page does |
| 446 | 449 | * not vanish from under us. |
| 447 | 450 | */ |
| 448 | −static void get_map(struct kmem_cache *s, struct page *page, unsigned long *map) | |
| 451 | +static unsigned long *get_map(struct kmem_cache *s, struct page *page) | |
| 449 | 452 | { |
| 450 | 453 | void *p; |
| 451 | 454 | void *addr = page_address(page); |
| 452 | 455 | |
| 456 | + VM_BUG_ON(!irqs_disabled()); | |
| 457 | + | |
| 458 | + spin_lock(&object_map_lock); | |
| 459 | + | |
| 460 | + bitmap_zero(object_map, page->objects); | |
| 461 | + | |
| 453 | 462 | for (p = page->freelist; p; p = get_freepointer(s, p)) |
| 454 | − set_bit(slab_index(p, s, addr), map); | |
| 463 | + set_bit(slab_index(p, s, addr), object_map); | |
| 464 | + | |
| 465 | + return object_map; | |
| 466 | +} | |
| 467 | + | |
| 468 | +static void put_map(unsigned long *map) | |
| 469 | +{ | |
| 470 | + VM_BUG_ON(map != object_map); | |
| 471 | + lockdep_assert_held(&object_map_lock); | |
| 472 | + | |
| 473 | + spin_unlock(&object_map_lock); | |
| 455 | 474 | } |
| 456 | 475 | |
| 457 | 476 | static inline unsigned int size_from_object(struct kmem_cache *s) |
| @@ -3675,13 +3694,12 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page, · 3217 unmodified lines | ||
| 3675 | 3694 | #ifdef CONFIG_SLUB_DEBUG |
| 3676 | 3695 | void *addr = page_address(page); |
| 3677 | 3696 | void *p; |
| 3678 | − unsigned long *map = bitmap_zalloc(page->objects, GFP_ATOMIC); | |
| 3679 | − if (!map) | |
| 3680 | − return; | |
| 3697 | + unsigned long *map; | |
| 3698 | + | |
| 3681 | 3699 | slab_err(s, page, text, s->name); |
| 3682 | 3700 | slab_lock(page); |
| 3683 | 3701 | |
| 3684 | − get_map(s, page, map); | |
| 3702 | + map = get_map(s, page); | |
| 3685 | 3703 | for_each_object(p, s, addr, page->objects) { |
| 3686 | 3704 | |
| 3687 | 3705 | if (!test_bit(slab_index(p, s, addr), map)) { |
| @@ -3689,8 +3707,9 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page, · 1 unmodified line | ||
| 3689 | 3707 | print_tracking(s, p); |
| 3690 | 3708 | } |
| 3691 | 3709 | } |
| 3710 | + put_map(map); | |
| 3711 | + | |
| 3692 | 3712 | slab_unlock(page); |
| 3693 | − bitmap_free(map); | |
| 3694 | 3713 | #endif |
| 3695 | 3714 | } |
| 3696 | 3715 | |
| @@ -4384,19 +4403,19 @@ static int count_total(struct page *page) · 687 unmodified lines | ||
| 4384 | 4403 | #endif |
| 4385 | 4404 | |
| 4386 | 4405 | #ifdef CONFIG_SLUB_DEBUG |
| 4387 | −static void validate_slab(struct kmem_cache *s, struct page *page, | |
| 4388 | − unsigned long *map) | |
| 4406 | +static void validate_slab(struct kmem_cache *s, struct page *page) | |
| 4389 | 4407 | { |
| 4390 | 4408 | void *p; |
| 4391 | 4409 | void *addr = page_address(page); |
| 4410 | + unsigned long *map; | |
| 4411 | + | |
| 4412 | + slab_lock(page); | |
| 4392 | 4413 | |
| 4393 | 4414 | if (!check_slab(s, page) || !on_freelist(s, page, NULL)) |
| 4394 | − return; | |
| 4415 | + goto unlock; | |
| 4395 | 4416 | |
| 4396 | 4417 | /* Now we know that a valid freelist exists */ |
| 4397 | − bitmap_zero(map, page->objects); | |
| 4398 | − | |
| 4399 | − get_map(s, page, map); | |
| 4418 | + map = get_map(s, page); | |
| 4400 | 4419 | for_each_object(p, s, addr, page->objects) { |
| 4401 | 4420 | u8 val = test_bit(slab_index(p, s, addr), map) ? |
| 4402 | 4421 | SLUB_RED_INACTIVE : SLUB_RED_ACTIVE; |
| @@ -4404,18 +4423,13 @@ static void validate_slab(struct kmem_cache *s, struct page *page, · 1 unmodified line | ||
| 4404 | 4423 | if (!check_object(s, page, p, val)) |
| 4405 | 4424 | break; |
| 4406 | 4425 | } |
| 4407 | −} | |
| 4408 | − | |
| 4409 | −static void validate_slab_slab(struct kmem_cache *s, struct page *page, | |
| 4410 | − unsigned long *map) | |
| 4411 | −{ | |
| 4412 | − slab_lock(page); | |
| 4413 | − validate_slab(s, page, map); | |
| 4426 | + put_map(map); | |
| 4427 | +unlock: | |
| 4414 | 4428 | slab_unlock(page); |
| 4415 | 4429 | } |
| 4416 | 4430 | |
| 4417 | 4431 | static int validate_slab_node(struct kmem_cache *s, |
| 4418 | − struct kmem_cache_node *n, unsigned long *map) | |
| 4432 | + struct kmem_cache_node *n) | |
| 4419 | 4433 | { |
| 4420 | 4434 | unsigned long count = 0; |
| 4421 | 4435 | struct page *page; |
| @@ -4424,7 +4438,7 @@ static int validate_slab_node(struct kmem_cache *s, · 2 unmodified lines | ||
| 4424 | 4438 | spin_lock_irqsave(&n->list_lock, flags); |
| 4425 | 4439 | |
| 4426 | 4440 | list_for_each_entry(page, &n->partial, slab_list) { |
| 4427 | − validate_slab_slab(s, page, map); | |
| 4441 | + validate_slab(s, page); | |
| 4428 | 4442 | count++; |
| 4429 | 4443 | } |
| 4430 | 4444 | if (count != n->nr_partial) |
| @@ -4435,7 +4449,7 @@ static int validate_slab_node(struct kmem_cache *s, · 4 unmodified lines | ||
| 4435 | 4449 | goto out; |
| 4436 | 4450 | |
| 4437 | 4451 | list_for_each_entry(page, &n->full, slab_list) { |
| 4438 | − validate_slab_slab(s, page, map); | |
| 4452 | + validate_slab(s, page); | |
| 4439 | 4453 | count++; |
| 4440 | 4454 | } |
| 4441 | 4455 | if (count != atomic_long_read(&n->nr_slabs)) |
| @@ -4452,15 +4466,11 @@ static long validate_slab_cache(struct kmem_cache *s) · 10 unmodified lines | ||
| 4452 | 4466 | int node; |
| 4453 | 4467 | unsigned long count = 0; |
| 4454 | 4468 | struct kmem_cache_node *n; |
| 4455 | − unsigned long *map = bitmap_alloc(oo_objects(s->max), GFP_KERNEL); | |
| 4456 | − | |
| 4457 | − if (!map) | |
| 4458 | − return -ENOMEM; | |
| 4459 | 4469 | |
| 4460 | 4470 | flush_all(s); |
| 4461 | 4471 | for_each_kmem_cache_node(s, node, n) |
| 4462 | − count += validate_slab_node(s, n, map); | |
| 4463 | − bitmap_free(map); | |
| 4472 | + count += validate_slab_node(s, n); | |
| 4473 | + | |
| 4464 | 4474 | return count; |
| 4465 | 4475 | } |
| 4466 | 4476 | /* |
| @@ -4590,18 +4600,17 @@ static int add_location(struct loc_track *t, struct kmem_cache *s, · 123 unmodified lines | ||
| 4590 | 4600 | } |
| 4591 | 4601 | |
| 4592 | 4602 | static void process_slab(struct loc_track *t, struct kmem_cache *s, |
| 4593 | − struct page *page, enum track_item alloc, | |
| 4594 | − unsigned long *map) | |
| 4603 | + struct page *page, enum track_item alloc) | |
| 4595 | 4604 | { |
| 4596 | 4605 | void *addr = page_address(page); |
| 4597 | 4606 | void *p; |
| 4607 | + unsigned long *map; | |
| 4598 | 4608 | |
| 4599 | − bitmap_zero(map, page->objects); | |
| 4600 | − get_map(s, page, map); | |
| 4601 | − | |
| 4609 | + map = get_map(s, page); | |
| 4602 | 4610 | for_each_object(p, s, addr, page->objects) |
| 4603 | 4611 | if (!test_bit(slab_index(p, s, addr), map)) |
| 4604 | 4612 | add_location(t, s, get_track(s, p, alloc)); |
| 4613 | + put_map(map); | |
| 4605 | 4614 | } |
| 4606 | 4615 | |
| 4607 | 4616 | static int list_locations(struct kmem_cache *s, char *buf, |
| @@ -4612,11 +4621,9 @@ static int list_locations(struct kmem_cache *s, char *buf, · 4 unmodified lines | ||
| 4612 | 4621 | struct loc_track t = { 0, 0, NULL }; |
| 4613 | 4622 | int node; |
| 4614 | 4623 | struct kmem_cache_node *n; |
| 4615 | − unsigned long *map = bitmap_alloc(oo_objects(s->max), GFP_KERNEL); | |
| 4616 | 4624 | |
| 4617 | − if (!map || !alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location), | |
| 4618 | − GFP_KERNEL)) { | |
| 4619 | − bitmap_free(map); | |
| 4625 | + if (!alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location), | |
| 4626 | + GFP_KERNEL)) { | |
| 4620 | 4627 | return sprintf(buf, "Out of memory\n"); |
| 4621 | 4628 | } |
| 4622 | 4629 | /* Push back cpu slabs */ |
| @@ -4631,9 +4638,9 @@ static int list_locations(struct kmem_cache *s, char *buf, · 8 unmodified lines | ||
| 4631 | 4638 | |
| 4632 | 4639 | spin_lock_irqsave(&n->list_lock, flags); |
| 4633 | 4640 | list_for_each_entry(page, &n->partial, slab_list) |
| 4634 | − process_slab(&t, s, page, alloc, map); | |
| 4641 | + process_slab(&t, s, page, alloc); | |
| 4635 | 4642 | list_for_each_entry(page, &n->full, slab_list) |
| 4636 | − process_slab(&t, s, page, alloc, map); | |
| 4643 | + process_slab(&t, s, page, alloc); | |
| 4637 | 4644 | spin_unlock_irqrestore(&n->list_lock, flags); |
| 4638 | 4645 | } |
| 4639 | 4646 | |
| @@ -4682,7 +4689,6 @@ static int list_locations(struct kmem_cache *s, char *buf, · 42 unmodified lines | ||
| 4682 | 4689 | } |
| 4683 | 4690 | |
| 4684 | 4691 | free_loc_track(&t); |
| 4685 | − bitmap_free(map); | |
| 4686 | 4692 | if (!t.count) |
| 4687 | 4693 | len += sprintf(buf, "No data\n"); |
| 4688 | 4694 | return len; |
| @@ -789,7 +789,7 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, · 788 unmodified lines | ||
| 789 | 789 | ms->usage = NULL; |
| 790 | 790 | } |
| 791 | 791 | memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr); |
| 792 | − ms->section_mem_map = sparse_encode_mem_map(NULL, section_nr); | |
| 792 | + ms->section_mem_map = (unsigned long)NULL; | |
| 793 | 793 | } |
| 794 | 794 | |
| 795 | 795 | if (section_is_early && memmap) |
| @@ -813,8 +813,10 @@ void release_pages(struct page **pages, int nr) · 812 unmodified lines | ||
| 813 | 813 | * processing, and instead, expect a call to |
| 814 | 814 | * put_page_testzero(). |
| 815 | 815 | */ |
| 816 | − if (put_devmap_managed_page(page)) | |
| 816 | + if (page_is_devmap_managed(page)) { | |
| 817 | + put_devmap_managed_page(page); | |
| 817 | 818 | continue; |
| 819 | + } | |
| 818 | 820 | } |
| 819 | 821 | |
| 820 | 822 | page = compound_head(page); |
| @@ -1102,3 +1104,26 @@ void __init swap_setup(void) · 281 unmodified lines | ||
| 1102 | 1104 | * _really_ don't want to cluster much more |
| 1103 | 1105 | */ |
| 1104 | 1106 | } |
| 1107 | + | |
| 1108 | +#ifdef CONFIG_DEV_PAGEMAP_OPS | |
| 1109 | +void put_devmap_managed_page(struct page *page) | |
| 1110 | +{ | |
| 1111 | + int count; | |
| 1112 | + | |
| 1113 | + if (WARN_ON_ONCE(!page_is_devmap_managed(page))) | |
| 1114 | + return; | |
| 1115 | + | |
| 1116 | + count = page_ref_dec_return(page); | |
| 1117 | + | |
| 1118 | + /* | |
| 1119 | + * devmap page refcounts are 1-based, rather than 0-based: if | |
| 1120 | + * refcount is 1, then the page is free and the refcount is | |
| 1121 | + * stable because nobody holds a reference on the page. | |
| 1122 | + */ | |
| 1123 | + if (count == 1) | |
| 1124 | + free_devmap_managed_page(page); | |
| 1125 | + else if (!count) | |
| 1126 | + __put_page(page); | |
| 1127 | +} | |
| 1128 | +EXPORT_SYMBOL(put_devmap_managed_page); | |
| 1129 | +#endif | |
| @@ -2737,10 +2737,10 @@ static void *swap_next(struct seq_file *swap, void *v, loff_t *pos) · 2736 unmodified lines | ||
| 2737 | 2737 | else |
| 2738 | 2738 | type = si->type + 1; |
| 2739 | 2739 | |
| 2740 | + ++(*pos); | |
| 2740 | 2741 | for (; (si = swap_type_to_swap_info(type)); type++) { |
| 2741 | 2742 | if (!(si->flags & SWP_USED) || !si->swap_map) |
| 2742 | 2743 | continue; |
| 2743 | − ++*pos; | |
| 2744 | 2744 | return si; |
| 2745 | 2745 | } |
| 2746 | 2746 | |
| @@ -146,20 +146,6 @@ struct scan_control { · 145 unmodified lines | ||
| 146 | 146 | struct reclaim_state reclaim_state; |
| 147 | 147 | }; |
| 148 | 148 | |
| 149 | −#ifdef ARCH_HAS_PREFETCH | |
| 150 | −#define prefetch_prev_lru_page(_page, _base, _field) \ | |
| 151 | − do { \ | |
| 152 | − if ((_page)->lru.prev != _base) { \ | |
| 153 | − struct page *prev; \ | |
| 154 | − \ | |
| 155 | − prev = lru_to_page(&(_page->lru)); \ | |
| 156 | − prefetch(&prev->_field); \ | |
| 157 | − } \ | |
| 158 | − } while (0) | |
| 159 | −#else | |
| 160 | −#define prefetch_prev_lru_page(_page, _base, _field) do { } while (0) | |
| 161 | −#endif | |
| 162 | − | |
| 163 | 149 | #ifdef ARCH_HAS_PREFETCHW |
| 164 | 150 | #define prefetchw_prev_lru_page(_page, _base, _field) \ |
| 165 | 151 | do { \ |
| @@ -2695,7 +2681,7 @@ static void shrink_node_memcgs(pg_data_t *pgdat, struct scan_control *sc) · 2529 unmodified lines | ||
| 2695 | 2681 | } while ((memcg = mem_cgroup_iter(target_memcg, memcg, NULL))); |
| 2696 | 2682 | } |
| 2697 | 2683 | |
| 2698 | −static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc) | |
| 2684 | +static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) | |
| 2699 | 2685 | { |
| 2700 | 2686 | struct reclaim_state *reclaim_state = current->reclaim_state; |
| 2701 | 2687 | unsigned long nr_reclaimed, nr_scanned; |
| @@ -2874,8 +2860,6 @@ again: · 172 unmodified lines | ||
| 2874 | 2860 | */ |
| 2875 | 2861 | if (reclaimable) |
| 2876 | 2862 | pgdat->kswapd_failures = 0; |
| 2877 | − | |
| 2878 | − return reclaimable; | |
| 2879 | 2863 | } |
| 2880 | 2864 | |
| 2881 | 2865 | /* |
| @@ -4126,10 +4110,8 @@ module_init(kswapd_init) · 1244 unmodified lines | ||
| 4126 | 4110 | */ |
| 4127 | 4111 | int node_reclaim_mode __read_mostly; |
| 4128 | 4112 | |
| 4129 | −#define RECLAIM_OFF 0 | |
| 4130 | −#define RECLAIM_ZONE (1<<0) /* Run shrink_inactive_list on the zone */ | |
| 4131 | −#define RECLAIM_WRITE (1<<1) /* Writeout pages during reclaim */ | |
| 4132 | −#define RECLAIM_UNMAP (1<<2) /* Unmap pages during reclaim */ | |
| 4113 | +#define RECLAIM_WRITE (1<<0) /* Writeout pages during reclaim */ | |
| 4114 | +#define RECLAIM_UNMAP (1<<1) /* Unmap pages during reclaim */ | |
| 4133 | 4115 | |
| 4134 | 4116 | /* |
| 4135 | 4117 | * Priority for NODE_RECLAIM. This determines the fraction of pages |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include <linux/swapops.h> |
| 33 | 33 | #include <linux/writeback.h> |
| 34 | 34 | #include <linux/pagemap.h> |
| 35 | +#include <linux/workqueue.h> | |
| 35 | 36 | |
| 36 | 37 | /********************************* |
| 37 | 38 | * statistics |
| @@ -65,6 +66,11 @@ static u64 zswap_reject_kmemcache_fail; · 27 unmodified lines | ||
| 65 | 66 | /* Duplicate store was encountered (rare) */ |
| 66 | 67 | static u64 zswap_duplicate_entry; |
| 67 | 68 | |
| 69 | +/* Shrinker work queue */ | |
| 70 | +static struct workqueue_struct *shrink_wq; | |
| 71 | +/* Pool limit was hit, we need to calm down */ | |
| 72 | +static bool zswap_pool_reached_full; | |
| 73 | + | |
| 68 | 74 | /********************************* |
| 69 | 75 | * tunables |
| 70 | 76 | **********************************/ |
| @@ -109,6 +115,11 @@ module_param_cb(zpool, &zswap_zpool_param_ops, &zswap_zpool_type, 0644); · 38 unmodified lines | ||
| 109 | 115 | static unsigned int zswap_max_pool_percent = 20; |
| 110 | 116 | module_param_named(max_pool_percent, zswap_max_pool_percent, uint, 0644); |
| 111 | 117 | |
| 118 | +/* The threshold for accepting new pages after the max_pool_percent was hit */ | |
| 119 | +static unsigned int zswap_accept_thr_percent = 90; /* of max pool size */ | |
| 120 | +module_param_named(accept_threshold_percent, zswap_accept_thr_percent, | |
| 121 | + uint, 0644); | |
| 122 | + | |
| 112 | 123 | /* Enable/disable handling same-value filled pages (enabled by default) */ |
| 113 | 124 | static bool zswap_same_filled_pages_enabled = true; |
| 114 | 125 | module_param_named(same_filled_pages_enabled, zswap_same_filled_pages_enabled, |
| @@ -123,7 +134,8 @@ struct zswap_pool { · 8 unmodified lines | ||
| 123 | 134 | struct crypto_comp * __percpu *tfm; |
| 124 | 135 | struct kref kref; |
| 125 | 136 | struct list_head list; |
| 126 | − struct work_struct work; | |
| 137 | + struct work_struct release_work; | |
| 138 | + struct work_struct shrink_work; | |
| 127 | 139 | struct hlist_node node; |
| 128 | 140 | char tfm_name[CRYPTO_MAX_ALG_NAME]; |
| 129 | 141 | }; |
| @@ -214,6 +226,13 @@ static bool zswap_is_full(void) · 84 unmodified lines | ||
| 214 | 226 | DIV_ROUND_UP(zswap_pool_total_size, PAGE_SIZE); |
| 215 | 227 | } |
| 216 | 228 | |
| 229 | +static bool zswap_can_accept(void) | |
| 230 | +{ | |
| 231 | + return totalram_pages() * zswap_accept_thr_percent / 100 * | |
| 232 | + zswap_max_pool_percent / 100 > | |
| 233 | + DIV_ROUND_UP(zswap_pool_total_size, PAGE_SIZE); | |
| 234 | +} | |
| 235 | + | |
| 217 | 236 | static void zswap_update_total_size(void) |
| 218 | 237 | { |
| 219 | 238 | struct zswap_pool *pool; |
| @@ -501,6 +520,16 @@ static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor) · 281 unmodified lines | ||
| 501 | 520 | return NULL; |
| 502 | 521 | } |
| 503 | 522 | |
| 523 | +static void shrink_worker(struct work_struct *w) | |
| 524 | +{ | |
| 525 | + struct zswap_pool *pool = container_of(w, typeof(*pool), | |
| 526 | + shrink_work); | |
| 527 | + | |
| 528 | + if (zpool_shrink(pool->zpool, 1, NULL)) | |
| 529 | + zswap_reject_reclaim_fail++; | |
| 530 | + zswap_pool_put(pool); | |
| 531 | +} | |
| 532 | + | |
| 504 | 533 | static struct zswap_pool *zswap_pool_create(char *type, char *compressor) |
| 505 | 534 | { |
| 506 | 535 | struct zswap_pool *pool; |
| @@ -551,6 +580,7 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor) · 44 unmodified lines | ||
| 551 | 580 | */ |
| 552 | 581 | kref_init(&pool->kref); |
| 553 | 582 | INIT_LIST_HEAD(&pool->list); |
| 583 | + INIT_WORK(&pool->shrink_work, shrink_worker); | |
| 554 | 584 | |
| 555 | 585 | zswap_pool_debug("created", pool); |
| 556 | 586 | |
| @@ -624,7 +654,8 @@ static int __must_check zswap_pool_get(struct zswap_pool *pool) · 67 unmodified lines | ||
| 624 | 654 | |
| 625 | 655 | static void __zswap_pool_release(struct work_struct *work) |
| 626 | 656 | { |
| 627 | − struct zswap_pool *pool = container_of(work, typeof(*pool), work); | |
| 657 | + struct zswap_pool *pool = container_of(work, typeof(*pool), | |
| 658 | + release_work); | |
| 628 | 659 | |
| 629 | 660 | synchronize_rcu(); |
| 630 | 661 | |
| @@ -647,8 +678,8 @@ static void __zswap_pool_empty(struct kref *kref) · 16 unmodified lines | ||
| 647 | 678 | |
| 648 | 679 | list_del_rcu(&pool->list); |
| 649 | 680 | |
| 650 | − INIT_WORK(&pool->work, __zswap_pool_release); | |
| 651 | − schedule_work(&pool->work); | |
| 681 | + INIT_WORK(&pool->release_work, __zswap_pool_release); | |
| 682 | + schedule_work(&pool->release_work); | |
| 652 | 683 | |
| 653 | 684 | spin_unlock(&zswap_pools_lock); |
| 654 | 685 | } |
| @@ -942,22 +973,6 @@ end: · 287 unmodified lines | ||
| 942 | 973 | return ret; |
| 943 | 974 | } |
| 944 | 975 | |
| 945 | −static int zswap_shrink(void) | |
| 946 | −{ | |
| 947 | − struct zswap_pool *pool; | |
| 948 | − int ret; | |
| 949 | − | |
| 950 | − pool = zswap_pool_last_get(); | |
| 951 | − if (!pool) | |
| 952 | − return -ENOENT; | |
| 953 | − | |
| 954 | − ret = zpool_shrink(pool->zpool, 1, NULL); | |
| 955 | − | |
| 956 | − zswap_pool_put(pool); | |
| 957 | − | |
| 958 | − return ret; | |
| 959 | −} | |
| 960 | − | |
| 961 | 976 | static int zswap_is_page_same_filled(void *ptr, unsigned long *value) |
| 962 | 977 | { |
| 963 | 978 | unsigned int pos; |
| @@ -1011,21 +1026,23 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset, · 47 unmodified lines | ||
| 1011 | 1026 | |
| 1012 | 1027 | /* reclaim space if needed */ |
| 1013 | 1028 | if (zswap_is_full()) { |
| 1029 | + struct zswap_pool *pool; | |
| 1030 | + | |
| 1014 | 1031 | zswap_pool_limit_hit++; |
| 1015 | − if (zswap_shrink()) { | |
| 1016 | − zswap_reject_reclaim_fail++; | |
| 1017 | − ret = -ENOMEM; | |
| 1018 | − goto reject; | |
| 1019 | − } | |
| 1032 | + zswap_pool_reached_full = true; | |
| 1033 | + pool = zswap_pool_last_get(); | |
| 1034 | + if (pool) | |
| 1035 | + queue_work(shrink_wq, &pool->shrink_work); | |
| 1036 | + ret = -ENOMEM; | |
| 1037 | + goto reject; | |
| 1038 | + } | |
| 1020 | 1039 | |
| 1021 | − /* A second zswap_is_full() check after | |
| 1022 | − * zswap_shrink() to make sure it's now | |
| 1023 | − * under the max_pool_percent | |
| 1024 | − */ | |
| 1025 | − if (zswap_is_full()) { | |
| 1040 | + if (zswap_pool_reached_full) { | |
| 1041 | + if (!zswap_can_accept()) { | |
| 1026 | 1042 | ret = -ENOMEM; |
| 1027 | 1043 | goto reject; |
| 1028 | − } | |
| 1044 | + } else | |
| 1045 | + zswap_pool_reached_full = false; | |
| 1029 | 1046 | } |
| 1030 | 1047 | |
| 1031 | 1048 | /* allocate entry */ |
| @@ -1332,11 +1349,18 @@ static int __init init_zswap(void) · 300 unmodified lines | ||
| 1332 | 1349 | zswap_enabled = false; |
| 1333 | 1350 | } |
| 1334 | 1351 | |
| 1352 | + shrink_wq = create_workqueue("zswap-shrink"); | |
| 1353 | + if (!shrink_wq) | |
| 1354 | + goto fallback_fail; | |
| 1355 | + | |
| 1335 | 1356 | frontswap_register_ops(&zswap_frontswap_ops); |
| 1336 | 1357 | if (zswap_debugfs_init()) |
| 1337 | 1358 | pr_warn("debugfs initialization failed\n"); |
| 1338 | 1359 | return 0; |
| 1339 | 1360 | |
| 1361 | +fallback_fail: | |
| 1362 | + if (pool) | |
| 1363 | + zswap_pool_destroy(pool); | |
| 1340 | 1364 | hp_fail: |
| 1341 | 1365 | cpuhp_remove_state(CPUHP_MM_ZSWP_MEM_PREPARE); |
| 1342 | 1366 | dstmem_fail: |
| @@ -212,7 +212,7 @@ static int xdp_umem_map_pages(struct xdp_umem *umem) · 211 unmodified lines | ||
| 212 | 212 | |
| 213 | 213 | static void xdp_umem_unpin_pages(struct xdp_umem *umem) |
| 214 | 214 | { |
| 215 | − put_user_pages_dirty_lock(umem->pgs, umem->npgs, true); | |
| 215 | + unpin_user_pages_dirty_lock(umem->pgs, umem->npgs, true); | |
| 216 | 216 | |
| 217 | 217 | kfree(umem->pgs); |
| 218 | 218 | umem->pgs = NULL; |
| @@ -291,7 +291,7 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem) · 72 unmodified lines | ||
| 291 | 291 | return -ENOMEM; |
| 292 | 292 | |
| 293 | 293 | down_read(¤t->mm->mmap_sem); |
| 294 | − npgs = get_user_pages(umem->address, umem->npgs, | |
| 294 | + npgs = pin_user_pages(umem->address, umem->npgs, | |
| 295 | 295 | gup_flags | FOLL_LONGTERM, &umem->pgs[0], NULL); |
| 296 | 296 | up_read(¤t->mm->mmap_sem); |
| 297 | 297 | |
| @@ -39,6 +39,8 @@ accout||account · 38 unmodified lines | ||
| 39 | 39 | accquire||acquire |
| 40 | 40 | accquired||acquired |
| 41 | 41 | accross||across |
| 42 | +accumalate||accumulate | |
| 43 | +accumalator||accumulator | |
| 42 | 44 | acessable||accessible |
| 43 | 45 | acess||access |
| 44 | 46 | acessing||accessing |
| @@ -106,6 +108,7 @@ alogrithm||algorithm · 61 unmodified lines | ||
| 106 | 108 | alot||a lot |
| 107 | 109 | alow||allow |
| 108 | 110 | alows||allows |
| 111 | +alreay||already | |
| 109 | 112 | alredy||already |
| 110 | 113 | altough||although |
| 111 | 114 | alue||value |
| @@ -241,6 +244,7 @@ calender||calendar · 129 unmodified lines | ||
| 241 | 244 | calescing||coalescing |
| 242 | 245 | calle||called |
| 243 | 246 | callibration||calibration |
| 247 | +callled||called | |
| 244 | 248 | calucate||calculate |
| 245 | 249 | calulate||calculate |
| 246 | 250 | cancelation||cancellation |
| @@ -311,6 +315,7 @@ compaibility||compatibility · 64 unmodified lines | ||
| 311 | 315 | comparsion||comparison |
| 312 | 316 | compatability||compatibility |
| 313 | 317 | compatable||compatible |
| 318 | +compatibililty||compatibility | |
| 314 | 319 | compatibiliy||compatibility |
| 315 | 320 | compatibilty||compatibility |
| 316 | 321 | compatiblity||compatibility |
| @@ -330,6 +335,7 @@ comunication||communication · 13 unmodified lines | ||
| 330 | 335 | conbination||combination |
| 331 | 336 | conditionaly||conditionally |
| 332 | 337 | conditon||condition |
| 338 | +condtion||condition | |
| 333 | 339 | conected||connected |
| 334 | 340 | conector||connector |
| 335 | 341 | connecetd||connected |
| @@ -388,6 +394,8 @@ dafault||default · 52 unmodified lines | ||
| 388 | 394 | deafult||default |
| 389 | 395 | deamon||daemon |
| 390 | 396 | debouce||debounce |
| 397 | +decendant||descendant | |
| 398 | +decendants||descendants | |
| 391 | 399 | decompres||decompress |
| 392 | 400 | decsribed||described |
| 393 | 401 | decription||description |
| @@ -411,11 +419,13 @@ delare||declare · 17 unmodified lines | ||
| 411 | 419 | delares||declares |
| 412 | 420 | delaring||declaring |
| 413 | 421 | delemiter||delimiter |
| 422 | +delievered||delivered | |
| 414 | 423 | demodualtor||demodulator |
| 415 | 424 | demension||dimension |
| 416 | 425 | dependancies||dependencies |
| 417 | 426 | dependancy||dependency |
| 418 | 427 | dependant||dependent |
| 428 | +dependend||dependent | |
| 419 | 429 | depreacted||deprecated |
| 420 | 430 | depreacte||deprecate |
| 421 | 431 | desactivate||deactivate |
| @@ -791,6 +801,7 @@ ireelevant||irrelevant · 369 unmodified lines | ||
| 791 | 801 | irrelevent||irrelevant |
| 792 | 802 | isnt||isn't |
| 793 | 803 | isssue||issue |
| 804 | +issus||issues | |
| 794 | 805 | iternations||iterations |
| 795 | 806 | itertation||iteration |
| 796 | 807 | itslef||itself |
| @@ -995,6 +1006,7 @@ peice||piece · 198 unmodified lines | ||
| 995 | 1006 | pendantic||pedantic |
| 996 | 1007 | peprocessor||preprocessor |
| 997 | 1008 | perfoming||performing |
| 1009 | +perfomring||performing | |
| 998 | 1010 | peripherial||peripheral |
| 999 | 1011 | permissons||permissions |
| 1000 | 1012 | peroid||period |
| @@ -1166,6 +1178,8 @@ retreive||retrieve · 165 unmodified lines | ||
| 1166 | 1178 | retreiving||retrieving |
| 1167 | 1179 | retrive||retrieve |
| 1168 | 1180 | retrived||retrieved |
| 1181 | +retrun||return | |
| 1182 | +retun||return | |
| 1169 | 1183 | retuned||returned |
| 1170 | 1184 | reudce||reduce |
| 1171 | 1185 | reuest||request |
| @@ -18,6 +18,9 @@ · 17 unmodified lines | ||
| 18 | 18 | #define GUP_LONGTERM_BENCHMARK _IOWR('g', 2, struct gup_benchmark) |
| 19 | 19 | #define GUP_BENCHMARK _IOWR('g', 3, struct gup_benchmark) |
| 20 | 20 | |
| 21 | +/* Just the flags we need, copied from mm.h: */ | |
| 22 | +#define FOLL_WRITE 0x01 /* check pte is writable */ | |
| 23 | + | |
| 21 | 24 | struct gup_benchmark { |
| 22 | 25 | __u64 get_delta_usec; |
| 23 | 26 | __u64 put_delta_usec; |
| @@ -85,7 +88,8 @@ int main(int argc, char **argv) · 61 unmodified lines | ||
| 85 | 88 | } |
| 86 | 89 | |
| 87 | 90 | gup.nr_pages_per_call = nr_pages; |
| 88 | − gup.flags = write; | |
| 91 | + if (write) | |
| 92 | + gup.flags |= FOLL_WRITE; | |
| 89 | 93 | |
| 90 | 94 | fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR); |
| 91 | 95 | if (fd == -1) |
| @@ -720,11 +720,11 @@ static void slab_debug(struct slabinfo *s) · 719 unmodified lines | ||
| 720 | 720 | return; |
| 721 | 721 | |
| 722 | 722 | if (sanity && !s->sanity_checks) { |
| 723 | − set_obj(s, "sanity", 1); | |
| 723 | + set_obj(s, "sanity_checks", 1); | |
| 724 | 724 | } |
| 725 | 725 | if (!sanity && s->sanity_checks) { |
| 726 | 726 | if (slab_empty(s)) |
| 727 | − set_obj(s, "sanity", 0); | |
| 727 | + set_obj(s, "sanity_checks", 0); | |
| 728 | 728 | else |
| 729 | 729 | fprintf(stderr, "%s not empty cannot disable sanity checks\n", s->name); |
| 730 | 730 | } |