Skip to content

Commit 0a6efab

Browse files
dtoralexandrebelloni
authored andcommitted
rtc: cmos: avoid taking rtc_lock for extended period of time
On my device reading entirety of /sys/devices/pnp0/00:03/cmos_nvram0/nvmem takes about 9 msec during which time interrupts are off on the CPU that does the read and the thread that performs the read can not be migrated or preempted by another higher priority thread (RT or not). Allow readers and writers be preempted by taking and releasing rtc_lock spinlock for each individual byte read or written rather than once per read/write request. Signed-off-by: Dmitry Torokhov <[email protected]> Reviewed-by: Mateusz Jończyk <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent d448837 commit 0a6efab

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

drivers/rtc/rtc-cmos.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -645,18 +645,17 @@ static int cmos_nvram_read(void *priv, unsigned int off, void *val,
645645
unsigned char *buf = val;
646646

647647
off += NVRAM_OFFSET;
648-
spin_lock_irq(&rtc_lock);
649-
for (; count; count--, off++) {
648+
for (; count; count--, off++, buf++) {
649+
guard(spinlock_irq)(&rtc_lock);
650650
if (off < 128)
651-
*buf++ = CMOS_READ(off);
651+
*buf = CMOS_READ(off);
652652
else if (can_bank2)
653-
*buf++ = cmos_read_bank2(off);
653+
*buf = cmos_read_bank2(off);
654654
else
655-
break;
655+
return -EIO;
656656
}
657-
spin_unlock_irq(&rtc_lock);
658657

659-
return count ? -EIO : 0;
658+
return 0;
660659
}
661660

662661
static int cmos_nvram_write(void *priv, unsigned int off, void *val,
@@ -671,23 +670,23 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val,
671670
* NVRAM to update, updating checksums is also part of its job.
672671
*/
673672
off += NVRAM_OFFSET;
674-
spin_lock_irq(&rtc_lock);
675-
for (; count; count--, off++) {
673+
for (; count; count--, off++, buf++) {
676674
/* don't trash RTC registers */
677675
if (off == cmos->day_alrm
678676
|| off == cmos->mon_alrm
679677
|| off == cmos->century)
680-
buf++;
681-
else if (off < 128)
682-
CMOS_WRITE(*buf++, off);
678+
continue;
679+
680+
guard(spinlock_irq)(&rtc_lock);
681+
if (off < 128)
682+
CMOS_WRITE(*buf, off);
683683
else if (can_bank2)
684-
cmos_write_bank2(*buf++, off);
684+
cmos_write_bank2(*buf, off);
685685
else
686-
break;
686+
return -EIO;
687687
}
688-
spin_unlock_irq(&rtc_lock);
689688

690-
return count ? -EIO : 0;
689+
return 0;
691690
}
692691

693692
/*----------------------------------------------------------------*/

0 commit comments

Comments
 (0)