rtc: cmos: avoid taking rtc_lock for extended period of time
[ Upstream commit 0a6efab33eab4e973db26d9f90c3e97a7a82e399 ] 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 <dmitry.torokhov@gmail.com> Reviewed-by: Mateusz Jończyk <mat.jonczyk@o2.pl> Link: https://lore.kernel.org/r/Zxv8QWR21AV4ztC5@google.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
80be263f3f
commit
2c9502ac83
@ -645,18 +645,17 @@ static int cmos_nvram_read(void *priv, unsigned int off, void *val,
|
||||
unsigned char *buf = val;
|
||||
|
||||
off += NVRAM_OFFSET;
|
||||
spin_lock_irq(&rtc_lock);
|
||||
for (; count; count--, off++) {
|
||||
for (; count; count--, off++, buf++) {
|
||||
guard(spinlock_irq)(&rtc_lock);
|
||||
if (off < 128)
|
||||
*buf++ = CMOS_READ(off);
|
||||
*buf = CMOS_READ(off);
|
||||
else if (can_bank2)
|
||||
*buf++ = cmos_read_bank2(off);
|
||||
*buf = cmos_read_bank2(off);
|
||||
else
|
||||
break;
|
||||
return -EIO;
|
||||
}
|
||||
spin_unlock_irq(&rtc_lock);
|
||||
|
||||
return count ? -EIO : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
* NVRAM to update, updating checksums is also part of its job.
|
||||
*/
|
||||
off += NVRAM_OFFSET;
|
||||
spin_lock_irq(&rtc_lock);
|
||||
for (; count; count--, off++) {
|
||||
for (; count; count--, off++, buf++) {
|
||||
/* don't trash RTC registers */
|
||||
if (off == cmos->day_alrm
|
||||
|| off == cmos->mon_alrm
|
||||
|| off == cmos->century)
|
||||
buf++;
|
||||
else if (off < 128)
|
||||
CMOS_WRITE(*buf++, off);
|
||||
else if (can_bank2)
|
||||
cmos_write_bank2(*buf++, off);
|
||||
else
|
||||
break;
|
||||
}
|
||||
spin_unlock_irq(&rtc_lock);
|
||||
continue;
|
||||
|
||||
return count ? -EIO : 0;
|
||||
guard(spinlock_irq)(&rtc_lock);
|
||||
if (off < 128)
|
||||
CMOS_WRITE(*buf, off);
|
||||
else if (can_bank2)
|
||||
cmos_write_bank2(*buf, off);
|
||||
else
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
Loading…
Reference in New Issue
Block a user