Skip to content

Commit 35b2b16

Browse files
jognesspmladek
authored andcommitted
printk: use atomic64_t for devkmsg_user.seq
@user->seq is indirectly protected by @logbuf_lock. Once @logbuf_lock is removed, @user->seq will be no longer safe from an atomicity point of view. In preparation for the removal of @logbuf_lock, change it to atomic64_t to provide this safety. Signed-off-by: John Ogness <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 7d7a23a commit 35b2b16

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

kernel/printk/printk.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ static ssize_t msg_print_ext_body(char *buf, size_t size,
662662

663663
/* /dev/kmsg - userspace message inject/listen interface */
664664
struct devkmsg_user {
665-
u64 seq;
665+
atomic64_t seq;
666666
struct ratelimit_state rs;
667667
struct mutex lock;
668668
char buf[CONSOLE_EXT_LOG_MAX];
@@ -763,7 +763,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
763763
return ret;
764764

765765
logbuf_lock_irq();
766-
if (!prb_read_valid(prb, user->seq, r)) {
766+
if (!prb_read_valid(prb, atomic64_read(&user->seq), r)) {
767767
if (file->f_flags & O_NONBLOCK) {
768768
ret = -EAGAIN;
769769
logbuf_unlock_irq();
@@ -772,15 +772,15 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
772772

773773
logbuf_unlock_irq();
774774
ret = wait_event_interruptible(log_wait,
775-
prb_read_valid(prb, user->seq, r));
775+
prb_read_valid(prb, atomic64_read(&user->seq), r));
776776
if (ret)
777777
goto out;
778778
logbuf_lock_irq();
779779
}
780780

781-
if (r->info->seq != user->seq) {
781+
if (r->info->seq != atomic64_read(&user->seq)) {
782782
/* our last seen message is gone, return error and reset */
783-
user->seq = r->info->seq;
783+
atomic64_set(&user->seq, r->info->seq);
784784
ret = -EPIPE;
785785
logbuf_unlock_irq();
786786
goto out;
@@ -791,7 +791,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
791791
&r->text_buf[0], r->info->text_len,
792792
&r->info->dev_info);
793793

794-
user->seq = r->info->seq + 1;
794+
atomic64_set(&user->seq, r->info->seq + 1);
795795
logbuf_unlock_irq();
796796

797797
if (len > count) {
@@ -831,19 +831,19 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
831831
switch (whence) {
832832
case SEEK_SET:
833833
/* the first record */
834-
user->seq = prb_first_valid_seq(prb);
834+
atomic64_set(&user->seq, prb_first_valid_seq(prb));
835835
break;
836836
case SEEK_DATA:
837837
/*
838838
* The first record after the last SYSLOG_ACTION_CLEAR,
839839
* like issued by 'dmesg -c'. Reading /dev/kmsg itself
840840
* changes no global state, and does not clear anything.
841841
*/
842-
user->seq = latched_seq_read_nolock(&clear_seq);
842+
atomic64_set(&user->seq, latched_seq_read_nolock(&clear_seq));
843843
break;
844844
case SEEK_END:
845845
/* after the last record */
846-
user->seq = prb_next_seq(prb);
846+
atomic64_set(&user->seq, prb_next_seq(prb));
847847
break;
848848
default:
849849
ret = -EINVAL;
@@ -864,9 +864,9 @@ static __poll_t devkmsg_poll(struct file *file, poll_table *wait)
864864
poll_wait(file, &log_wait, wait);
865865

866866
logbuf_lock_irq();
867-
if (prb_read_valid_info(prb, user->seq, &info, NULL)) {
867+
if (prb_read_valid_info(prb, atomic64_read(&user->seq), &info, NULL)) {
868868
/* return error when data has vanished underneath us */
869-
if (info.seq != user->seq)
869+
if (info.seq != atomic64_read(&user->seq))
870870
ret = EPOLLIN|EPOLLRDNORM|EPOLLERR|EPOLLPRI;
871871
else
872872
ret = EPOLLIN|EPOLLRDNORM;
@@ -905,7 +905,7 @@ static int devkmsg_open(struct inode *inode, struct file *file)
905905
&user->text_buf[0], sizeof(user->text_buf));
906906

907907
logbuf_lock_irq();
908-
user->seq = prb_first_valid_seq(prb);
908+
atomic64_set(&user->seq, prb_first_valid_seq(prb));
909909
logbuf_unlock_irq();
910910

911911
file->private_data = user;

0 commit comments

Comments
 (0)