Message ID | 20220423212623.1957011-10-Jason@zx2c4.com |
---|---|
State | New |
Headers | show |
Series | archs/random: fallback to best raw ktime when no cycle counter | expand |
On Sat, 23 Apr 2022, Jason A. Donenfeld wrote: > diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h > index b05bb70a2e46..8cfa485d19e6 100644 > --- a/arch/mips/include/asm/timex.h > +++ b/arch/mips/include/asm/timex.h [...] > + if (cpu_has_3kex) > + c0_random = (read_c0_random() >> 8) & 0x3f; Hmm, I wonder whether we do need to mask the contents of the register out here given that known implementations return zeros in reserved bits. Even though R3000 documentation I have access to makes no guarantee as to the values of the reserved bits here I think we can safely proceed according to what systems we do actually support do (even though it only saves one instruction). > else > - return 0; /* no usable register */ > + c0_random = read_c0_random() & 0x3f; Here the architecture guarantees unused bits to be zero, but the number of them varies between implementations. However we'll only ever use this leg for the R4000/R4400 processors, which have 48 TLB entries, and for the Ingenic XBurst cores, which I have now verified in documentation (which user-reported dumps from /proc/cpuinfo are consistent with) that have 32 TLB entries. So I think this mask operation can go as well. I guess these updates can be made with a follow-up change though. Maciej
Hey Maciej, On Tue, Apr 26, 2022 at 09:28:39PM +0100, Maciej W. Rozycki wrote: > On Sat, 23 Apr 2022, Jason A. Donenfeld wrote: > > > diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h > > index b05bb70a2e46..8cfa485d19e6 100644 > > --- a/arch/mips/include/asm/timex.h > > +++ b/arch/mips/include/asm/timex.h > [...] > > + if (cpu_has_3kex) > > + c0_random = (read_c0_random() >> 8) & 0x3f; > > Hmm, I wonder whether we do need to mask the contents of the register out > here given that known implementations return zeros in reserved bits. Even > though R3000 documentation I have access to makes no guarantee as to the > values of the reserved bits here I think we can safely proceed according > to what systems we do actually support do (even though it only saves one > instruction). > > > else > > - return 0; /* no usable register */ > > + c0_random = read_c0_random() & 0x3f; > > Here the architecture guarantees unused bits to be zero, but the number > of them varies between implementations. However we'll only ever use this > leg for the R4000/R4400 processors, which have 48 TLB entries, and for the > Ingenic XBurst cores, which I have now verified in documentation (which > user-reported dumps from /proc/cpuinfo are consistent with) that have 32 > TLB entries. So I think this mask operation can go as well. > > I guess these updates can be made with a follow-up change though. There is lots of optimization potential on a few fronts we've identified in this thread. Let's save these for a follow-up. I'd rather this initial one be at least somewhat simple, so that as it gets optimized, it'll be easy to handle regressions. Also, it probably makes sense for you to send the patches for these, since you have both the hardware chops and the hardware itself to assess these ideas. I am interested in the topic though, so please do CC me. Jason
Hey Maciej, On Wed, Apr 27, 2022 at 3:29 AM Jason A. Donenfeld <Jason@zx2c4.com> wrote: > > Hey Maciej, > > On Tue, Apr 26, 2022 at 09:28:39PM +0100, Maciej W. Rozycki wrote: > > On Sat, 23 Apr 2022, Jason A. Donenfeld wrote: > > > > > diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h > > > index b05bb70a2e46..8cfa485d19e6 100644 > > > --- a/arch/mips/include/asm/timex.h > > > +++ b/arch/mips/include/asm/timex.h > > [...] > > > + if (cpu_has_3kex) > > > + c0_random = (read_c0_random() >> 8) & 0x3f; > > > > Hmm, I wonder whether we do need to mask the contents of the register out > > here given that known implementations return zeros in reserved bits. Even > > though R3000 documentation I have access to makes no guarantee as to the > > values of the reserved bits here I think we can safely proceed according > > to what systems we do actually support do (even though it only saves one > > instruction). > > > > > else > > > - return 0; /* no usable register */ > > > + c0_random = read_c0_random() & 0x3f; > > > > Here the architecture guarantees unused bits to be zero, but the number > > of them varies between implementations. However we'll only ever use this > > leg for the R4000/R4400 processors, which have 48 TLB entries, and for the > > Ingenic XBurst cores, which I have now verified in documentation (which > > user-reported dumps from /proc/cpuinfo are consistent with) that have 32 > > TLB entries. So I think this mask operation can go as well. > > > > I guess these updates can be made with a follow-up change though. > > There is lots of optimization potential on a few fronts we've identified > in this thread. Let's save these for a follow-up. I'd rather this > initial one be at least somewhat simple, so that as it gets optimized, > it'll be easy to handle regressions. Also, it probably makes sense for > you to send the patches for these, since you have both the hardware > chops and the hardware itself to assess these ideas. I am interested in > the topic though, so please do CC me. Everything has been upstream for a little while now, which means development of this can move back to the proper MIPS tree like normal. Did you want to submit some optimizations? Would be happy to look at whatever you have in mind. Jason
Hi Jason, > > There is lots of optimization potential on a few fronts we've identified > > in this thread. Let's save these for a follow-up. I'd rather this > > initial one be at least somewhat simple, so that as it gets optimized, > > it'll be easy to handle regressions. Also, it probably makes sense for > > you to send the patches for these, since you have both the hardware > > chops and the hardware itself to assess these ideas. I am interested in > > the topic though, so please do CC me. > > Everything has been upstream for a little while now, which means > development of this can move back to the proper MIPS tree like normal. > Did you want to submit some optimizations? Would be happy to look at > whatever you have in mind. Thank you for the heads-up! Unfortunately I'm a little stuck at the moment, especially as one of my main MIPS machines (a 5Kc Malta system) died mid-May while operating. It seems to be a faulty CPU core card and the base board may be fine, though I cannot know for sure as I only have one each and I don't have a logic analyser or at least a JTAG probe to peek at the system and see what's going on inside. If anyone knows a source of a replacement Malta, preferably with a 5Kc CoreLV CPU module or another 64-bit hard core card (a number of different ones have been made), then I'll appreciate if you let me know. I feel rather depressed knowing that many if not most hit the scrapper already while they could still find a good use. Somehow it is easier to get way more obsolete hardware from 1980/90s just because it was general purpose rather than niche. Otherwise I'll try to get back to this stuff later in the year with whatever I have that still runs, but don't hold your breath. Sorry! Maciej
Hi Jason, > > Unfortunately I'm a little stuck at the moment, especially as one of my > > main MIPS machines (a 5Kc Malta system) died mid-May while operating. It > > seems to be a faulty CPU core card and the base board may be fine, though > > I cannot know for sure as I only have one each and I don't have a logic > > analyser or at least a JTAG probe to peek at the system and see what's > > going on inside. > > > > If anyone knows a source of a replacement Malta, preferably with a 5Kc > > CoreLV CPU module or another 64-bit hard core card (a number of different > > ones have been made), then I'll appreciate if you let me know. I feel > > rather depressed knowing that many if not most hit the scrapper already > > while they could still find a good use. Somehow it is easier to get way > > more obsolete hardware from 1980/90s just because it was general purpose > > rather than niche. > > > > Otherwise I'll try to get back to this stuff later in the year with > > whatever I have that still runs, but don't hold your breath. Sorry! > > Just thought I'd poke you about this, on the off chance that you found > some new hardware and feel like tinkering around with cycle counters > again. Some old MIPS platforms were recently dropped, too, which makes > me wonder whether there's some room for more simplification here. I have a replacement CPU module now, but it is not the same as the old one was and it has a built-in different system controller (a MIPS SOC-it IP implementation) rather than a discrete Galileo GT-64120A chip the original module had. And the system controller suffers from PCI handling issues, i.e. the YAMON firmware hangs in PCI enumeration if there are more than 2 buses present (my configuration used to have 3) and in Linux one of the option cards seems not to respond to MMIO accesses (a mapping error?), with exactly the same hardware configuration that worked just fine with the Galileo. I had to pull some hardware to make the system boot at all. It's not clear to me yet if these are symptoms of hardware errata or bugs in the respective pieces of software, but I fear debugging fatal issues has to take precedence over optimisations for me, so I have to defer cycle counter tinkering yet more. NB the replacement CPU module is also 32-bit rather than 64-bit as the broken one was and therefore I'm still looking for a replacement 64-bit CPU module. Malta CPU modules seem exceedingly scarce nowadays, it seems easier to track down a 30 years old MIPS R3000 DECstation machine, sigh... Maciej
diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h index b05bb70a2e46..8cfa485d19e6 100644 --- a/arch/mips/include/asm/timex.h +++ b/arch/mips/include/asm/timex.h @@ -76,25 +76,24 @@ static inline cycles_t get_cycles(void) else return 0; /* no usable counter */ } +#define get_cycles get_cycles /* * Like get_cycles - but where c0_count is not available we desperately * use c0_random in an attempt to get at least a little bit of entropy. - * - * R6000 and R6000A neither have a count register nor a random register. - * That leaves no entropy source in the CPU itself. */ static inline unsigned long random_get_entropy(void) { - unsigned int prid = read_c0_prid(); - unsigned int imp = prid & PRID_IMP_MASK; + unsigned int c0_random; - if (can_use_mips_counter(prid)) + if (can_use_mips_counter(read_c0_prid())) return read_c0_count(); - else if (likely(imp != PRID_IMP_R6000 && imp != PRID_IMP_R6000A)) - return read_c0_random(); + + if (cpu_has_3kex) + c0_random = (read_c0_random() >> 8) & 0x3f; else - return 0; /* no usable register */ + c0_random = read_c0_random() & 0x3f; + return (random_get_entropy_fallback() << 6) | (0x3f - c0_random); } #define random_get_entropy random_get_entropy