1
0
mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2026-01-11 17:10:13 +00:00

27 hotfixes. 12 are cc:stable, 18 are MM.

There's a three patch series from Jiayuan Chen which fixes some issues
 with KASAN and vmalloc.  Apart from that it's the usual shower of
 singletons - please see the respective changelogs for details.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCaVIWxwAKCRDdBJ7gKXxA
 jt6HAP49s/mEIIbuZbqnX8hxDrvYdYffs+RsSLPEZoR+yKG/7gD/VqSZhMoPw53b
 rMZ56djXNjWxsOAfiVbZit3SFuQfnQ4=
 =5rGD
 -----END PGP SIGNATURE-----

Merge tag 'mm-hotfixes-stable-2025-12-28-21-50' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc fixes from Andrew Morton:
 "27 hotfixes.  12 are cc:stable, 18 are MM.

  There's a patch series from Jiayuan Chen which fixes some
  issues with KASAN and vmalloc. Apart from that it's the usual
  shower of singletons - please see the respective changelogs
  for details"

* tag 'mm-hotfixes-stable-2025-12-28-21-50' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (27 commits)
  mm/ksm: fix pte_unmap_unlock of wrong address in break_ksm_pmd_entry
  mm/page_owner: fix memory leak in page_owner_stack_fops->release()
  mm/memremap: fix spurious large folio warning for FS-DAX
  MAINTAINERS: notify the "Device Memory" community of memory hotplug changes
  sparse: update MAINTAINERS info
  mm/page_alloc: report 1 as zone_batchsize for !CONFIG_MMU
  mm: consider non-anon swap cache folios in folio_expected_ref_count()
  rust: maple_tree: rcu_read_lock() in destructor to silence lockdep
  mm: memcg: fix unit conversion for K() macro in OOM log
  mm: fixup pfnmap memory failure handling to use pgoff
  tools/mm/page_owner_sort: fix timestamp comparison for stable sorting
  selftests/mm: fix thread state check in uffd-unit-tests
  kernel/kexec: fix IMA when allocation happens in CMA area
  kernel/kexec: change the prototype of kimage_map_segment()
  MAINTAINERS: add ABI headers to KHO and LIVE UPDATE
  .mailmap: remove one of the entries for WangYuli
  mm/damon/vaddr: fix missing pte_unmap_unlock in damos_va_migrate_pmd_entry()
  MAINTAINERS: update one straggling entry for Bartosz Golaszewski
  mm/page_alloc: change all pageblocks migrate type on coalescing
  mm: leafops.h: correct kernel-doc function param. names
  ...
This commit is contained in:
Linus Torvalds 2025-12-29 11:40:38 -08:00
commit 0b34fd0fea
26 changed files with 163 additions and 59 deletions

View File

@ -127,7 +127,8 @@ Barry Song <baohua@kernel.org> <Baohua.Song@csr.com>
Barry Song <baohua@kernel.org> <barry.song@analog.com>
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
Bartosz Golaszewski <brgl@bgdev.pl> <bgolaszewski@baylibre.com>
Bartosz Golaszewski <brgl@kernel.org> <bartosz.golaszewski@linaro.org>
Bartosz Golaszewski <brgl@kernel.org> <bgolaszewski@baylibre.com>
Ben Dooks <ben-linux@fluff.org> <ben.dooks@simtec.co.uk>
Ben Dooks <ben-linux@fluff.org> <ben.dooks@sifive.com>
Ben Gardner <bgardner@wabtec.com>
@ -857,7 +858,6 @@ Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com>
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
WangYuli <wangyuli@aosc.io> <wangyl5933@chinaunicom.cn>
WangYuli <wangyuli@aosc.io> <wangyuli@deepin.org>
WangYuli <wangyuli@aosc.io> <wangyuli@uniontech.com>
Weiwen Hu <huweiwen@linux.alibaba.com> <sehuww@mail.scut.edu.cn>
WeiXiong Liao <gmpy.liaowx@gmail.com> <liaoweixiong@allwinnertech.com>
Wen Gong <quic_wgong@quicinc.com> <wgong@codeaurora.org>

View File

@ -13959,6 +13959,7 @@ S: Maintained
F: Documentation/admin-guide/mm/kho.rst
F: Documentation/core-api/kho/*
F: include/linux/kexec_handover.h
F: include/linux/kho/
F: kernel/liveupdate/kexec_handover*
F: lib/test_kho.c
F: tools/testing/selftests/kho/
@ -14637,6 +14638,7 @@ S: Maintained
F: Documentation/core-api/liveupdate.rst
F: Documentation/mm/memfd_preservation.rst
F: Documentation/userspace-api/liveupdate.rst
F: include/linux/kho/abi/
F: include/linux/liveupdate.h
F: include/linux/liveupdate/
F: include/uapi/linux/liveupdate.h
@ -16426,6 +16428,7 @@ MEMORY HOT(UN)PLUG
M: David Hildenbrand <david@kernel.org>
M: Oscar Salvador <osalvador@suse.de>
L: linux-mm@kvack.org
L: linux-cxl@vger.kernel.org
S: Maintained
F: Documentation/admin-guide/mm/memory-hotplug.rst
F: Documentation/core-api/memory-hotplug.rst
@ -16751,6 +16754,7 @@ F: tools/testing/selftests/mm/transhuge-stress.c
MEMORY MANAGEMENT - USERFAULTFD
M: Andrew Morton <akpm@linux-foundation.org>
M: Mike Rapoport <rppt@kernel.org>
R: Peter Xu <peterx@redhat.com>
L: linux-mm@kvack.org
S: Maintained
@ -21345,7 +21349,7 @@ F: Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml
F: drivers/net/wwan/qcom_bam_dmux.c
QUALCOMM BLUETOOTH DRIVER
M: Bartosz Golaszewski <brgl@bgdev.pl>
M: Bartosz Golaszewski <brgl@kernel.org>
L: linux-arm-msm@vger.kernel.org
S: Maintained
F: drivers/bluetooth/btqca.[ch]
@ -24571,7 +24575,7 @@ F: drivers/tty/vcc.c
F: include/linux/sunserialcore.h
SPARSE CHECKER
M: "Luc Van Oostenryck" <luc.vanoostenryck@gmail.com>
M: Chris Li <sparse@chrisli.org>
L: linux-sparse@vger.kernel.org
S: Maintained
W: https://sparse.docs.kernel.org/

View File

@ -44,6 +44,7 @@ struct gen_pool;
* @nr: The number of zeroed bits we're looking for
* @data: optional additional data used by the callback
* @pool: the pool being allocated from
* @start_addr: start address of memory chunk
*/
typedef unsigned long (*genpool_algo_t)(unsigned long *map,
unsigned long size,

View File

@ -28,6 +28,7 @@ typedef unsigned int __bitwise kasan_vmalloc_flags_t;
#define KASAN_VMALLOC_INIT ((__force kasan_vmalloc_flags_t)0x01u)
#define KASAN_VMALLOC_VM_ALLOC ((__force kasan_vmalloc_flags_t)0x02u)
#define KASAN_VMALLOC_PROT_NORMAL ((__force kasan_vmalloc_flags_t)0x04u)
#define KASAN_VMALLOC_KEEP_TAG ((__force kasan_vmalloc_flags_t)0x08u)
#define KASAN_VMALLOC_PAGE_RANGE 0x1 /* Apply exsiting page range */
#define KASAN_VMALLOC_TLB_FLUSH 0x2 /* TLB flush */
@ -630,6 +631,16 @@ static __always_inline void kasan_poison_vmalloc(const void *start,
__kasan_poison_vmalloc(start, size);
}
void __kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms,
kasan_vmalloc_flags_t flags);
static __always_inline void
kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms,
kasan_vmalloc_flags_t flags)
{
if (kasan_enabled())
__kasan_unpoison_vmap_areas(vms, nr_vms, flags);
}
#else /* CONFIG_KASAN_VMALLOC */
static inline void kasan_populate_early_vm_area_shadow(void *start,
@ -654,6 +665,11 @@ static inline void *kasan_unpoison_vmalloc(const void *start,
static inline void kasan_poison_vmalloc(const void *start, unsigned long size)
{ }
static __always_inline void
kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms,
kasan_vmalloc_flags_t flags)
{ }
#endif /* CONFIG_KASAN_VMALLOC */
#if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \

View File

@ -530,7 +530,7 @@ extern bool kexec_file_dbg_print;
#define kexec_dprintk(fmt, arg...) \
do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0)
extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size);
extern void *kimage_map_segment(struct kimage *image, int idx);
extern void kimage_unmap_segment(void *buffer);
#else /* !CONFIG_KEXEC_CORE */
struct pt_regs;
@ -540,7 +540,7 @@ static inline void __crash_kexec(struct pt_regs *regs) { }
static inline void crash_kexec(struct pt_regs *regs) { }
static inline int kexec_should_crash(struct task_struct *p) { return 0; }
static inline int kexec_crash_loaded(void) { return 0; }
static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size)
static inline void *kimage_map_segment(struct kimage *image, int idx)
{ return NULL; }
static inline void kimage_unmap_segment(void *buffer) { }
#define kexec_in_progress false

View File

@ -133,7 +133,7 @@ static inline bool softleaf_is_none(softleaf_t entry)
/**
* softleaf_type() - Identify the type of leaf entry.
* @enntry: Leaf entry.
* @entry: Leaf entry.
*
* Returns: the leaf entry type associated with @entry.
*/
@ -534,7 +534,7 @@ static inline bool pte_is_uffd_wp_marker(pte_t pte)
/**
* pte_is_uffd_marker() - Does this PTE entry encode a userfault-specific marker
* leaf entry?
* @entry: Leaf entry.
* @pte: PTE entry.
*
* It's useful to be able to determine which leaf entries encode UFFD-specific
* markers so we can handle these correctly.

View File

@ -9,6 +9,8 @@ struct pfn_address_space;
struct pfn_address_space {
struct interval_tree_node node;
struct address_space *mapping;
int (*pfn_to_vma_pgoff)(struct vm_area_struct *vma,
unsigned long pfn, pgoff_t *pgoff);
};
int register_pfn_address_space(struct pfn_address_space *pfn_space);

View File

@ -2459,10 +2459,10 @@ static inline int folio_expected_ref_count(const struct folio *folio)
if (WARN_ON_ONCE(page_has_type(&folio->page) && !folio_test_hugetlb(folio)))
return 0;
if (folio_test_anon(folio)) {
/* One reference per page from the swapcache. */
ref_count += folio_test_swapcache(folio) << order;
} else {
/* One reference per page from the swapcache. */
ref_count += folio_test_swapcache(folio) << order;
if (!folio_test_anon(folio)) {
/* One reference per page from the pagecache. */
ref_count += !!folio->mapping << order;
/* One reference from PG_private. */

View File

@ -953,17 +953,24 @@ int kimage_load_segment(struct kimage *image, int idx)
return result;
}
void *kimage_map_segment(struct kimage *image,
unsigned long addr, unsigned long size)
void *kimage_map_segment(struct kimage *image, int idx)
{
unsigned long addr, size, eaddr;
unsigned long src_page_addr, dest_page_addr = 0;
unsigned long eaddr = addr + size;
kimage_entry_t *ptr, entry;
struct page **src_pages;
unsigned int npages;
struct page *cma;
void *vaddr = NULL;
int i;
cma = image->segment_cma[idx];
if (cma)
return page_address(cma);
addr = image->segment[idx].mem;
size = image->segment[idx].memsz;
eaddr = addr + size;
/*
* Collect the source pages and map them in a contiguous VA range.
*/
@ -1004,7 +1011,8 @@ void *kimage_map_segment(struct kimage *image,
void kimage_unmap_segment(void *segment_buffer)
{
vunmap(segment_buffer);
if (is_vmalloc_addr(segment_buffer))
vunmap(segment_buffer);
}
struct kexec_load_limit {

View File

@ -40,6 +40,8 @@ int idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid,
if (WARN_ON_ONCE(!(idr->idr_rt.xa_flags & ROOT_IS_IDR)))
idr->idr_rt.xa_flags |= IDR_RT_MARKER;
if (max < base)
return -ENOSPC;
id = (id < base) ? 0 : id - base;
radix_tree_iter_init(&iter, id);

View File

@ -743,7 +743,7 @@ huge_out:
if (!folio)
continue;
if (damos_va_filter_out(s, folio, walk->vma, addr, pte, NULL))
return 0;
continue;
damos_va_migrate_dests_add(folio, walk->vma, addr, dests,
migration_lists);
nr = folio_nr_pages(folio);

View File

@ -28,6 +28,7 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/bug.h>
#include <linux/vmalloc.h>
#include "kasan.h"
#include "../slab.h"
@ -575,3 +576,34 @@ bool __kasan_check_byte(const void *address, unsigned long ip)
}
return true;
}
#ifdef CONFIG_KASAN_VMALLOC
void __kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms,
kasan_vmalloc_flags_t flags)
{
unsigned long size;
void *addr;
int area;
u8 tag;
/*
* If KASAN_VMALLOC_KEEP_TAG was set at this point, all vms[] pointers
* would be unpoisoned with the KASAN_TAG_KERNEL which would disable
* KASAN checks down the line.
*/
if (WARN_ON_ONCE(flags & KASAN_VMALLOC_KEEP_TAG))
return;
size = vms[0]->size;
addr = vms[0]->addr;
vms[0]->addr = __kasan_unpoison_vmalloc(addr, size, flags);
tag = get_tag(vms[0]->addr);
for (area = 1 ; area < nr_vms ; area++) {
size = vms[area]->size;
addr = set_tag(vms[area]->addr, tag);
vms[area]->addr =
__kasan_unpoison_vmalloc(addr, size, flags | KASAN_VMALLOC_KEEP_TAG);
}
}
#endif

View File

@ -361,7 +361,7 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
return (void *)start;
}
tag = kasan_random_tag();
tag = (flags & KASAN_VMALLOC_KEEP_TAG) ? get_tag(start) : kasan_random_tag();
start = set_tag(start, tag);
/* Unpoison and initialize memory up to size. */

View File

@ -631,7 +631,9 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
!(flags & KASAN_VMALLOC_PROT_NORMAL))
return (void *)start;
start = set_tag(start, kasan_random_tag());
if (unlikely(!(flags & KASAN_VMALLOC_KEEP_TAG)))
start = set_tag(start, kasan_random_tag());
kasan_unpoison(start, size, false);
return (void *)start;
}

View File

@ -650,7 +650,7 @@ static int break_ksm_pmd_entry(pmd_t *pmdp, unsigned long addr, unsigned long en
}
}
out_unlock:
pte_unmap_unlock(ptep, ptl);
pte_unmap_unlock(start_ptep, ptl);
return found;
}

View File

@ -5638,6 +5638,6 @@ void mem_cgroup_show_protected_memory(struct mem_cgroup *memcg)
memcg = root_mem_cgroup;
pr_warn("Memory cgroup min protection %lukB -- low protection %lukB",
K(atomic_long_read(&memcg->memory.children_min_usage)*PAGE_SIZE),
K(atomic_long_read(&memcg->memory.children_low_usage)*PAGE_SIZE));
K(atomic_long_read(&memcg->memory.children_min_usage)),
K(atomic_long_read(&memcg->memory.children_low_usage)));
}

View File

@ -2161,6 +2161,9 @@ int register_pfn_address_space(struct pfn_address_space *pfn_space)
{
guard(mutex)(&pfn_space_lock);
if (!pfn_space->pfn_to_vma_pgoff)
return -EINVAL;
if (interval_tree_iter_first(&pfn_space_itree,
pfn_space->node.start,
pfn_space->node.last))
@ -2183,10 +2186,10 @@ void unregister_pfn_address_space(struct pfn_address_space *pfn_space)
}
EXPORT_SYMBOL_GPL(unregister_pfn_address_space);
static void add_to_kill_pfn(struct task_struct *tsk,
struct vm_area_struct *vma,
struct list_head *to_kill,
unsigned long pfn)
static void add_to_kill_pgoff(struct task_struct *tsk,
struct vm_area_struct *vma,
struct list_head *to_kill,
pgoff_t pgoff)
{
struct to_kill *tk;
@ -2197,12 +2200,12 @@ static void add_to_kill_pfn(struct task_struct *tsk,
}
/* Check for pgoff not backed by struct page */
tk->addr = vma_address(vma, pfn, 1);
tk->addr = vma_address(vma, pgoff, 1);
tk->size_shift = PAGE_SHIFT;
if (tk->addr == -EFAULT)
pr_info("Unable to find address %lx in %s\n",
pfn, tsk->comm);
pgoff, tsk->comm);
get_task_struct(tsk);
tk->tsk = tsk;
@ -2212,11 +2215,12 @@ static void add_to_kill_pfn(struct task_struct *tsk,
/*
* Collect processes when the error hit a PFN not backed by struct page.
*/
static void collect_procs_pfn(struct address_space *mapping,
static void collect_procs_pfn(struct pfn_address_space *pfn_space,
unsigned long pfn, struct list_head *to_kill)
{
struct vm_area_struct *vma;
struct task_struct *tsk;
struct address_space *mapping = pfn_space->mapping;
i_mmap_lock_read(mapping);
rcu_read_lock();
@ -2226,9 +2230,12 @@ static void collect_procs_pfn(struct address_space *mapping,
t = task_early_kill(tsk, true);
if (!t)
continue;
vma_interval_tree_foreach(vma, &mapping->i_mmap, pfn, pfn) {
if (vma->vm_mm == t->mm)
add_to_kill_pfn(t, vma, to_kill, pfn);
vma_interval_tree_foreach(vma, &mapping->i_mmap, 0, ULONG_MAX) {
pgoff_t pgoff;
if (vma->vm_mm == t->mm &&
!pfn_space->pfn_to_vma_pgoff(vma, pfn, &pgoff))
add_to_kill_pgoff(t, vma, to_kill, pgoff);
}
}
rcu_read_unlock();
@ -2264,7 +2271,7 @@ static int memory_failure_pfn(unsigned long pfn, int flags)
struct pfn_address_space *pfn_space =
container_of(node, struct pfn_address_space, node);
collect_procs_pfn(pfn_space->mapping, pfn, &tokill);
collect_procs_pfn(pfn_space, pfn, &tokill);
mf_handled = true;
}

View File

@ -427,8 +427,6 @@ void free_zone_device_folio(struct folio *folio)
if (folio_test_anon(folio)) {
for (i = 0; i < nr; i++)
__ClearPageAnonExclusive(folio_page(folio, i));
} else {
VM_WARN_ON_ONCE(folio_test_large(folio));
}
/*

View File

@ -914,6 +914,17 @@ buddy_merge_likely(unsigned long pfn, unsigned long buddy_pfn,
NULL) != NULL;
}
static void change_pageblock_range(struct page *pageblock_page,
int start_order, int migratetype)
{
int nr_pageblocks = 1 << (start_order - pageblock_order);
while (nr_pageblocks--) {
set_pageblock_migratetype(pageblock_page, migratetype);
pageblock_page += pageblock_nr_pages;
}
}
/*
* Freeing function for a buddy system allocator.
*
@ -1000,7 +1011,7 @@ static inline void __free_one_page(struct page *page,
* expand() down the line puts the sub-blocks
* on the right freelists.
*/
set_pageblock_migratetype(buddy, migratetype);
change_pageblock_range(buddy, order, migratetype);
}
combined_pfn = buddy_pfn & pfn;
@ -2147,17 +2158,6 @@ bool pageblock_unisolate_and_move_free_pages(struct zone *zone, struct page *pag
#endif /* CONFIG_MEMORY_ISOLATION */
static void change_pageblock_range(struct page *pageblock_page,
int start_order, int migratetype)
{
int nr_pageblocks = 1 << (start_order - pageblock_order);
while (nr_pageblocks--) {
set_pageblock_migratetype(pageblock_page, migratetype);
pageblock_page += pageblock_nr_pages;
}
}
static inline bool boost_watermark(struct zone *zone)
{
unsigned long max_boost;
@ -5924,7 +5924,7 @@ static int zone_batchsize(struct zone *zone)
* recycled, this leads to the once large chunks of space being
* fragmented and becoming unavailable for high-order allocations.
*/
return 0;
return 1;
#endif
}

View File

@ -952,7 +952,7 @@ static const struct file_operations page_owner_stack_fops = {
.open = page_owner_stack_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.release = seq_release_private,
};
static int page_owner_threshold_get(void *data, u64 *val)

View File

@ -4331,7 +4331,9 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align
*/
if (size <= alloced_size) {
kasan_unpoison_vmalloc(p + old_size, size - old_size,
KASAN_VMALLOC_PROT_NORMAL);
KASAN_VMALLOC_PROT_NORMAL |
KASAN_VMALLOC_VM_ALLOC |
KASAN_VMALLOC_KEEP_TAG);
/*
* No need to zero memory here, as unused memory will have
* already been zeroed at initial allocation time or during
@ -5025,9 +5027,7 @@ retry:
* With hardware tag-based KASAN, marking is skipped for
* non-VM_ALLOC mappings, see __kasan_unpoison_vmalloc().
*/
for (area = 0; area < nr_vms; area++)
vms[area]->addr = kasan_unpoison_vmalloc(vms[area]->addr,
vms[area]->size, KASAN_VMALLOC_PROT_NORMAL);
kasan_unpoison_vmap_areas(vms, nr_vms, KASAN_VMALLOC_PROT_NORMAL);
kfree(vas);
return vms;

View File

@ -265,7 +265,16 @@ impl<T: ForeignOwnable> MapleTree<T> {
loop {
// This uses the raw accessor because we're destroying pointers without removing them
// from the maple tree, which is only valid because this is the destructor.
let ptr = ma_state.mas_find_raw(usize::MAX);
//
// Take the rcu lock because mas_find_raw() requires that you hold either the spinlock
// or the rcu read lock. This is only really required if memory reclaim might
// reallocate entries in the tree, as we otherwise have exclusive access. That feature
// doesn't exist yet, so for now, taking the rcu lock only serves the purpose of
// silencing lockdep.
let ptr = {
let _rcu = kernel::sync::rcu::Guard::new();
ma_state.mas_find_raw(usize::MAX)
};
if ptr.is_null() {
break;
}

View File

@ -250,9 +250,7 @@ void ima_kexec_post_load(struct kimage *image)
if (!image->ima_buffer_addr)
return;
ima_kexec_buffer = kimage_map_segment(image,
image->ima_buffer_addr,
image->ima_buffer_size);
ima_kexec_buffer = kimage_map_segment(image, image->ima_segment_index);
if (!ima_kexec_buffer) {
pr_err("Could not map measurements buffer.\n");
return;

View File

@ -181,7 +181,11 @@ static int compare_ts(const void *p1, const void *p2)
{
const struct block_list *l1 = p1, *l2 = p2;
return l1->ts_nsec < l2->ts_nsec ? -1 : 1;
if (l1->ts_nsec < l2->ts_nsec)
return -1;
if (l1->ts_nsec > l2->ts_nsec)
return 1;
return 0;
}
static int compare_cull_condition(const void *p1, const void *p2)

View File

@ -57,6 +57,26 @@ void idr_alloc_test(void)
idr_destroy(&idr);
}
void idr_alloc2_test(void)
{
int id;
struct idr idr = IDR_INIT_BASE(idr, 1);
id = idr_alloc(&idr, idr_alloc2_test, 0, 1, GFP_KERNEL);
assert(id == -ENOSPC);
id = idr_alloc(&idr, idr_alloc2_test, 1, 2, GFP_KERNEL);
assert(id == 1);
id = idr_alloc(&idr, idr_alloc2_test, 0, 1, GFP_KERNEL);
assert(id == -ENOSPC);
id = idr_alloc(&idr, idr_alloc2_test, 0, 2, GFP_KERNEL);
assert(id == -ENOSPC);
idr_destroy(&idr);
}
void idr_replace_test(void)
{
DEFINE_IDR(idr);
@ -409,6 +429,7 @@ void idr_checks(void)
idr_replace_test();
idr_alloc_test();
idr_alloc2_test();
idr_null_test();
idr_nowait_test();
idr_get_next_test(0);

View File

@ -1317,7 +1317,7 @@ static thread_state thread_state_get(pid_t tid)
p = strstr(tmp, header);
if (p) {
/* For example, "State:\tD (disk sleep)" */
c = *(p + sizeof(header) - 1);
c = *(p + strlen(header));
return c == 'D' ?
THR_STATE_UNINTERRUPTIBLE : THR_STATE_UNKNOWN;
}