Skip to content

Commit 3b347e4

Browse files
committed
Merge tag 'trace-v6.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull tracing fixes from Steven Rostedt: - Make sure 32-bit applications using user events have aligned access when running on a 64-bit kernel. - Add cond_resched in the loop that handles converting enums in print_fmt string is trace events. - Fix premature wake ups of polling processes in the tracing ring buffer. When a task polls waiting for a percentage of the ring buffer to be filled, the writer still will wake it up at every event. Add the polling's percentage to the "shortest_full" list to tell the writer when to wake it up. - For eventfs dir lookups on dynamic events, an event system's only event could be removed, leaving its dentry with no children. This is totally legitimate. But in eventfs_release() it must not access the children array, as it is only allocated when the dentry has children. * tag 'trace-v6.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: eventfs: Test for dentries array allocated in eventfs_release() tracing/user_events: Align set_bit() address for all archs tracing: relax trace_event_eval_update() execution with cond_resched() ring-buffer: Update "shortest_full" in polling
2 parents 3b51796 + 2598bd3 commit 3b347e4

File tree

4 files changed

+56
-8
lines changed

4 files changed

+56
-8
lines changed

fs/tracefs/event_inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ static int eventfs_release(struct inode *inode, struct file *file)
421421
if (WARN_ON_ONCE(!dlist))
422422
return -EINVAL;
423423

424-
for (i = 0; dlist->dentries[i]; i++) {
424+
for (i = 0; dlist->dentries && dlist->dentries[i]; i++) {
425425
dput(dlist->dentries[i]);
426426
}
427427

kernel/trace/ring_buffer.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,9 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
11371137
if (full) {
11381138
poll_wait(filp, &work->full_waiters, poll_table);
11391139
work->full_waiters_pending = true;
1140+
if (!cpu_buffer->shortest_full ||
1141+
cpu_buffer->shortest_full > full)
1142+
cpu_buffer->shortest_full = full;
11401143
} else {
11411144
poll_wait(filp, &work->waiters, poll_table);
11421145
work->waiters_pending = true;

kernel/trace/trace_events.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2770,6 +2770,7 @@ void trace_event_eval_update(struct trace_eval_map **map, int len)
27702770
update_event_fields(call, map[i]);
27712771
}
27722772
}
2773+
cond_resched();
27732774
}
27742775
up_write(&trace_event_sem);
27752776
}

kernel/trace/trace_events_user.c

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,13 @@ struct user_event_enabler {
127127
/* Bit 7 is for freeing status of enablement */
128128
#define ENABLE_VAL_FREEING_BIT 7
129129

130-
/* Only duplicate the bit value */
131-
#define ENABLE_VAL_DUP_MASK ENABLE_VAL_BIT_MASK
130+
/* Bit 8 is for marking 32-bit on 64-bit */
131+
#define ENABLE_VAL_32_ON_64_BIT 8
132+
133+
#define ENABLE_VAL_COMPAT_MASK (1 << ENABLE_VAL_32_ON_64_BIT)
134+
135+
/* Only duplicate the bit and compat values */
136+
#define ENABLE_VAL_DUP_MASK (ENABLE_VAL_BIT_MASK | ENABLE_VAL_COMPAT_MASK)
132137

133138
#define ENABLE_BITOPS(e) (&(e)->values)
134139

@@ -174,6 +179,30 @@ struct user_event_validator {
174179
int flags;
175180
};
176181

182+
static inline void align_addr_bit(unsigned long *addr, int *bit,
183+
unsigned long *flags)
184+
{
185+
if (IS_ALIGNED(*addr, sizeof(long))) {
186+
#ifdef __BIG_ENDIAN
187+
/* 32 bit on BE 64 bit requires a 32 bit offset when aligned. */
188+
if (test_bit(ENABLE_VAL_32_ON_64_BIT, flags))
189+
*bit += 32;
190+
#endif
191+
return;
192+
}
193+
194+
*addr = ALIGN_DOWN(*addr, sizeof(long));
195+
196+
/*
197+
* We only support 32 and 64 bit values. The only time we need
198+
* to align is a 32 bit value on a 64 bit kernel, which on LE
199+
* is always 32 bits, and on BE requires no change when unaligned.
200+
*/
201+
#ifdef __LITTLE_ENDIAN
202+
*bit += 32;
203+
#endif
204+
}
205+
177206
typedef void (*user_event_func_t) (struct user_event *user, struct iov_iter *i,
178207
void *tpdata, bool *faulted);
179208

@@ -482,6 +511,7 @@ static int user_event_enabler_write(struct user_event_mm *mm,
482511
unsigned long *ptr;
483512
struct page *page;
484513
void *kaddr;
514+
int bit = ENABLE_BIT(enabler);
485515
int ret;
486516

487517
lockdep_assert_held(&event_mutex);
@@ -497,6 +527,8 @@ static int user_event_enabler_write(struct user_event_mm *mm,
497527
test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler))))
498528
return -EBUSY;
499529

530+
align_addr_bit(&uaddr, &bit, ENABLE_BITOPS(enabler));
531+
500532
ret = pin_user_pages_remote(mm->mm, uaddr, 1, FOLL_WRITE | FOLL_NOFAULT,
501533
&page, NULL);
502534

@@ -515,9 +547,9 @@ static int user_event_enabler_write(struct user_event_mm *mm,
515547

516548
/* Update bit atomically, user tracers must be atomic as well */
517549
if (enabler->event && enabler->event->status)
518-
set_bit(ENABLE_BIT(enabler), ptr);
550+
set_bit(bit, ptr);
519551
else
520-
clear_bit(ENABLE_BIT(enabler), ptr);
552+
clear_bit(bit, ptr);
521553

522554
kunmap_local(kaddr);
523555
unpin_user_pages_dirty_lock(&page, 1, true);
@@ -849,6 +881,12 @@ static struct user_event_enabler
849881
enabler->event = user;
850882
enabler->addr = uaddr;
851883
enabler->values = reg->enable_bit;
884+
885+
#if BITS_PER_LONG >= 64
886+
if (reg->enable_size == 4)
887+
set_bit(ENABLE_VAL_32_ON_64_BIT, ENABLE_BITOPS(enabler));
888+
#endif
889+
852890
retry:
853891
/* Prevents state changes from racing with new enablers */
854892
mutex_lock(&event_mutex);
@@ -2377,15 +2415,16 @@ static long user_unreg_get(struct user_unreg __user *ureg,
23772415
}
23782416

23792417
static int user_event_mm_clear_bit(struct user_event_mm *user_mm,
2380-
unsigned long uaddr, unsigned char bit)
2418+
unsigned long uaddr, unsigned char bit,
2419+
unsigned long flags)
23812420
{
23822421
struct user_event_enabler enabler;
23832422
int result;
23842423
int attempt = 0;
23852424

23862425
memset(&enabler, 0, sizeof(enabler));
23872426
enabler.addr = uaddr;
2388-
enabler.values = bit;
2427+
enabler.values = bit | flags;
23892428
retry:
23902429
/* Prevents state changes from racing with new enablers */
23912430
mutex_lock(&event_mutex);
@@ -2415,6 +2454,7 @@ static long user_events_ioctl_unreg(unsigned long uarg)
24152454
struct user_event_mm *mm = current->user_event_mm;
24162455
struct user_event_enabler *enabler, *next;
24172456
struct user_unreg reg;
2457+
unsigned long flags;
24182458
long ret;
24192459

24202460
ret = user_unreg_get(ureg, &reg);
@@ -2425,6 +2465,7 @@ static long user_events_ioctl_unreg(unsigned long uarg)
24252465
if (!mm)
24262466
return -ENOENT;
24272467

2468+
flags = 0;
24282469
ret = -ENOENT;
24292470

24302471
/*
@@ -2441,6 +2482,9 @@ static long user_events_ioctl_unreg(unsigned long uarg)
24412482
ENABLE_BIT(enabler) == reg.disable_bit) {
24422483
set_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler));
24432484

2485+
/* We must keep compat flags for the clear */
2486+
flags |= enabler->values & ENABLE_VAL_COMPAT_MASK;
2487+
24442488
if (!test_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler)))
24452489
user_event_enabler_destroy(enabler, true);
24462490

@@ -2454,7 +2498,7 @@ static long user_events_ioctl_unreg(unsigned long uarg)
24542498
/* Ensure bit is now cleared for user, regardless of event status */
24552499
if (!ret)
24562500
ret = user_event_mm_clear_bit(mm, reg.disable_addr,
2457-
reg.disable_bit);
2501+
reg.disable_bit, flags);
24582502

24592503
return ret;
24602504
}

0 commit comments

Comments
 (0)