Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3a6ba53
NFSv4: xattr handlers should check for absent nfs filehandles
PlaidCat Jan 16, 2026
49610e4
sched/isolation: add cpu_is_isolated() API
PlaidCat Jan 16, 2026
a89370c
blk-mq: don't schedule block kworker on isolated CPUs
PlaidCat Jan 16, 2026
d9d2ec4
blk-mq: add helper for checking if one CPU is mapped to specified hctx
PlaidCat Jan 16, 2026
e720393
blk-mq: setup queue ->tag_set before initializing hctx
PlaidCat Jan 16, 2026
1cfd102
ceph: fix race condition validating r_parent before applying state
PlaidCat Jan 16, 2026
2545526
ceph: fix race condition where r_parent becomes stale before sending …
PlaidCat Jan 16, 2026
0c60b39
perf/x86/intel/pebs: Fix PEBS timestamps overwritten
PlaidCat Jan 16, 2026
8a39b95
perf/x86/intel/ds: Fix the conversion from TSC to perf time
PlaidCat Jan 16, 2026
01d88e3
sctp: avoid NULL dereference when chunk data buffer is missing
PlaidCat Jan 16, 2026
243bc34
gfs2: Minor do_xmote cancelation fix
PlaidCat Jan 16, 2026
8b33fcd
gfs2: Get rid of unnecessary test_and_set_bit
PlaidCat Jan 16, 2026
b1e31dc
gfs2: simplify finish_xmote
PlaidCat Jan 16, 2026
f6dceaf
gfs2: run_queue cleanup
PlaidCat Jan 16, 2026
0131ea7
media: rc: Add support for another iMON 0xffdc device
PlaidCat Jan 16, 2026
673a6f1
media: imon: drop references only after device is no longer used
PlaidCat Jan 16, 2026
e43a432
media: imon: reorganize serialization
PlaidCat Jan 16, 2026
867395b
media: imon: fix a race condition in send_packet()
PlaidCat Jan 16, 2026
c481bc7
media: rc: fix races with imon_disconnect()
PlaidCat Jan 16, 2026
6162294
libceph: fix potential use-after-free in have_mon_and_osd_map()
PlaidCat Jan 16, 2026
4be5de5
Rebuild rocky8_10 with kernel-4.18.0-553.92.1.el8_10
PlaidCat Jan 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.rhelver
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RHEL_MINOR = 10
#
# Use this spot to avoid future merge conflicts.
# Do not trim this comment.
RHEL_RELEASE = 553.89.1
RHEL_RELEASE = 553.92.1

#
# ZSTREAM
Expand Down
31 changes: 26 additions & 5 deletions arch/x86/events/intel/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/sched/clock.h>

#include <asm/cpu_entry_area.h>
#include <asm/perf_event.h>
#include <asm/tlbflush.h>
#include <asm/insn.h>
#include <asm/io.h>
#include <asm/timer.h>

#include "../perf_event.h"

Expand Down Expand Up @@ -1541,6 +1543,27 @@ static u64 get_data_src(struct perf_event *event, u64 aux)
return val;
}

static void setup_pebs_time(struct perf_event *event,
struct perf_sample_data *data,
u64 tsc)
{
/* Converting to a user-defined clock is not supported yet. */
if (event->attr.use_clockid != 0)
return;

/*
* Doesn't support the conversion when the TSC is unstable.
* The TSC unstable case is a corner case and very unlikely to
* happen. If it happens, the TSC in a PEBS record will be
* dropped and fall back to perf_event_clock().
*/
if (!using_native_sched_clock() || !sched_clock_stable())
return;

data->time = native_sched_clock_from_tsc(tsc) + __sched_clock_offset;
data->sample_flags |= PERF_SAMPLE_TIME;
}

static void setup_pebs_fixed_sample_data(struct perf_event *event,
struct pt_regs *iregs, void *__pebs,
struct perf_sample_data *data,
Expand Down Expand Up @@ -1675,9 +1698,8 @@ static void setup_pebs_fixed_sample_data(struct perf_event *event,
*
* We can only do this for the default trace clock.
*/
if (x86_pmu.intel_cap.pebs_format >= 3 &&
event->attr.use_clockid == 0)
data->time = native_sched_clock_from_tsc(pebs->tsc);
if (x86_pmu.intel_cap.pebs_format >= 3)
setup_pebs_time(event, data, pebs->tsc);

if (has_branch_stack(event))
data->br_stack = &cpuc->lbr_stack;
Expand Down Expand Up @@ -1739,8 +1761,7 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
perf_sample_data_init(data, 0, event->hw.last_period);
data->period = event->hw.last_period;

if (event->attr.use_clockid == 0)
data->time = native_sched_clock_from_tsc(basic->tsc);
setup_pebs_time(event, data, basic->tsc);

/*
* We must however always use iregs for the unwinder to stay sane; the
Expand Down
85 changes: 71 additions & 14 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/crash_dump.h>
#include <linux/prefetch.h>
#include RH_KABI_HIDE_INCLUDE(<linux/sched/isolation.h>)

#include <trace/events/block.h>

Expand Down Expand Up @@ -1611,6 +1612,15 @@ static inline int blk_mq_first_mapped_cpu(struct blk_mq_hw_ctx *hctx)
return cpu;
}

/*
* ->next_cpu is always calculated from hctx->cpumask, so simply use
* it for speeding up the check
*/
static bool blk_mq_hctx_empty_cpumask(struct blk_mq_hw_ctx *hctx)
{
return hctx->next_cpu >= nr_cpu_ids;
}

/*
* It'd be great if the workqueue API had a way to pass
* in a mask and had some smarts for more clever placement.
Expand All @@ -1622,7 +1632,8 @@ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx)
bool tried = false;
int next_cpu = hctx->next_cpu;

if (hctx->queue->nr_hw_queues == 1)
/* Switch to unbound if no allowable CPUs in this hctx */
if (hctx->queue->nr_hw_queues == 1 || blk_mq_hctx_empty_cpumask(hctx))
return WORK_CPU_UNBOUND;

if (--hctx->next_cpu_batch <= 0) {
Expand Down Expand Up @@ -2648,23 +2659,38 @@ static bool blk_mq_hctx_has_requests(struct blk_mq_hw_ctx *hctx)
return data.has_rq;
}

static inline bool blk_mq_last_cpu_in_hctx(unsigned int cpu,
struct blk_mq_hw_ctx *hctx)
static bool blk_mq_hctx_has_online_cpu(struct blk_mq_hw_ctx *hctx,
unsigned int this_cpu)
{
if (cpumask_next_and(-1, hctx->cpumask, cpu_online_mask) != cpu)
return false;
if (cpumask_next_and(cpu, hctx->cpumask, cpu_online_mask) < nr_cpu_ids)
return false;
return true;
enum hctx_type type = hctx->type;
int cpu;

/*
* hctx->cpumask has to rule out isolated CPUs, but userspace still
* might submit IOs on these isolated CPUs, so use the queue map to
* check if all CPUs mapped to this hctx are offline
*/
for_each_online_cpu(cpu) {
struct blk_mq_hw_ctx *h = blk_mq_map_queue_type(hctx->queue,
type, cpu);

if (h != hctx)
continue;

/* this hctx has at least one online CPU */
if (this_cpu != cpu)
return true;
}

return false;
}

static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node)
{
struct blk_mq_hw_ctx *hctx = hlist_entry_safe(node,
struct blk_mq_hw_ctx, cpuhp_online);

if (!cpumask_test_cpu(cpu, hctx->cpumask) ||
!blk_mq_last_cpu_in_hctx(cpu, hctx))
if (blk_mq_hctx_has_online_cpu(hctx, cpu))
return 0;

/*
Expand All @@ -2691,12 +2717,28 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node)
return 0;
}

/*
* Check if one CPU is mapped to the specified hctx
*
* Isolated CPUs have been ruled out from hctx->cpumask, which is supposed
* to be used for scheduling kworker only. For other usage, please call this
* helper for checking if one CPU belongs to the specified hctx
*/
static bool blk_mq_cpu_mapped_to_hctx(unsigned int cpu,
const struct blk_mq_hw_ctx *hctx)
{
struct blk_mq_hw_ctx *mapped_hctx = blk_mq_map_queue_type(hctx->queue,
hctx->type, cpu);

return mapped_hctx == hctx;
}

static int blk_mq_hctx_notify_online(unsigned int cpu, struct hlist_node *node)
{
struct blk_mq_hw_ctx *hctx = hlist_entry_safe(node,
struct blk_mq_hw_ctx, cpuhp_online);

if (cpumask_test_cpu(cpu, hctx->cpumask))
if (blk_mq_cpu_mapped_to_hctx(cpu, hctx))
clear_bit(BLK_MQ_S_INACTIVE, &hctx->state);
return 0;
}
Expand All @@ -2714,7 +2756,7 @@ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node)
enum hctx_type type;

hctx = hlist_entry_safe(node, struct blk_mq_hw_ctx, cpuhp_dead);
if (!cpumask_test_cpu(cpu, hctx->cpumask))
if (!blk_mq_cpu_mapped_to_hctx(cpu, hctx))
return 0;

ctx = __blk_mq_get_ctx(hctx->queue, cpu);
Expand Down Expand Up @@ -3057,6 +3099,8 @@ static void blk_mq_map_swqueue(struct request_queue *q)
}

queue_for_each_hw_ctx(q, hctx, i) {
int cpu;

/*
* If no software queues are mapped to this hardware queue,
* disable it and free the request entries.
Expand All @@ -3083,6 +3127,15 @@ static void blk_mq_map_swqueue(struct request_queue *q)
*/
sbitmap_resize(&hctx->ctx_map, hctx->nr_ctx);

/*
* Rule out isolated CPUs from hctx->cpumask to avoid
* running block kworker on isolated CPUs
*/
for_each_cpu(cpu, hctx->cpumask) {
if (cpu_is_isolated(cpu))
cpumask_clear_cpu(cpu, hctx->cpumask);
}

/*
* Initialize batch roundrobin counts
*/
Expand Down Expand Up @@ -3392,6 +3445,12 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
if (!q->poll_cb)
goto err_exit;

/*
* ->tag_set has to be setup before initialize hctx, which cpuphp
* handler needs it for checking queue mapping
*/
q->tag_set = set;

if (blk_mq_alloc_ctxs(q))
goto err_exit;

Expand All @@ -3408,8 +3467,6 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
INIT_WORK(&q->timeout_work, blk_mq_timeout_work);
blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);

q->tag_set = set;

q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;
if (set->nr_maps > HCTX_TYPE_POLL &&
set->map[HCTX_TYPE_POLL].nr_queues)
Expand Down
Loading