tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: RFC: New userspace fetch/store API
Jason Thorpe <thorpej%me.com@localhost> wrote:
> The existing fetch(9) / store(9) APIs have some problems. Specifically:
>
> ==> Their return semantics mean that fuword() cannot disambiguate between
> an error condition (-1) and a legitimate fetch of -1 from user space.
>
> ==> “word” is poorly defined. For all practical purposes, it means
> “long”, and there is thus no way to fetch/store an “int” value on LP64
> platforms.
>
> ==> There are lots of legacy aliases lying about that are no longer
> meaningful (I-space and D-space variants, for example).
Thanks for working on this. Actually, I started the same revamp with a
similar API (suggested by matt@ at that time) a bunch of years ago.. but
lost interest and didn't finish.
> Outstanding question before I go too far down the rabbit hole: should I
> bother with the “intrsafe” variants? The only application for it in the
> tree right now is in the profiling code, as an optimization to avoid
> taking an AST when it’s time to bump the counters.
Please do not over-engineer it. IIRC, there are not that many use cases
of this API, the need for more variants didn't really increase over the
decade(s) and there is no need to provide a vast spectrum of functions.
They can be added later, if there will be a need.
Also, are there any uses of byte and short operations? If not, then I
think these variants should be eliminated. Nowadays, I would argue that
generally there should be no good reason to choose sub-word operations;
stick with the word size (it helps with the alignment too) or more.
>
> These functions may block (to service a page fault), and are NOT safe to
> call from any interrupt context.
>
Please make sure you add the asserts.
> The implementation is entirely in architecture-dependent code. The
> following fetch primitives must be supplied:
>
> int ufetch_8(const uint8_t *uaddr, uint8_t *valp);
> int ufetch_16(const uint16_t *uaddr, uint16_t *valp);
> int ufetch_32(const uint32_t *uaddr, uint32_t *valp);
> #ifdef _LP64
> int ufetch_64(const uint64_t *uaddr, uint64_t *valp);
> #endif
Please prefix the size with 'u' if you operate on unsigned types:
ufetch_u{8,16,32,64} and the same for ustore_*
> The following aliases must also be provided, mapped to the appropriate
> fixed-size primitives:
>
> int ufetch_char(const unsigned char *uaddr, unsigned char *valp);
> int ufetch_short(const unsigned short *uaddr, unsigned short *valp);
> int ufetch_int(const unsigned int *uaddr, unsigned int *valp);
> int ufetch_long(const unsigned long *uaddr, unsigned long *valp);
> int ufetch_ptr(const void **uaddr, void **valp);
>
> The following store primitives must be suppled:
>
> int ustore_8(uint8_t *uaddr, uint8_t val);
> int ustore_16(uint16_t *uaddr, uint16_t val);
> int ustore_32(uint32_t *uaddr, uint32_t val);
> #ifdef _LP64
> int ustore_64(uint64_t *uaddr, uint64_t val);
> #endif
>
> The following aliases must also be provided, mapped to the appropriate
> fixed-size primitives:
>
> int ustore_char(unsigned char *uaddr, unsigned char val);
> int ustore_short(unsigned short *uaddr, unsigned short val);
> int ustore_int(unsigned int *uaddr, unsigned int val);
> int ustore_long(unsigned long *uaddr, unsigned long val);
> int ustore_ptr(void **uaddr, void *val);
The same applies here (e.g. ustore_int becomes ustore_uint).
--
Mindaugas
Home |
Main Index |
Thread Index |
Old Index