On 11/12/2020 02:01, Al Viro wrote: > On Thu, Nov 19, 2020 at 05:12:44PM +0000, Pavel Begunkov wrote: >> On 19/11/2020 17:03, Christoph Hellwig wrote: >>> On Thu, Nov 19, 2020 at 03:29:43PM +0000, Pavel Begunkov wrote: >>>> The problem here is that iov_iter_is_*() helpers check types for >>>> equality, but all iterate_* helpers do bitwise ands. This confuses >>>> a compiler, so even if some cases were handled separately with >>>> iov_iter_is_*(), it can't eliminate and skip unreachable branches in >>>> following iterate*(). >>> >>> I think we need to kill the iov_iter_is_* helpers, renumber to not do >>> the pointless bitmask and just check for equality (might turn into a >>> bunch of nice switch statements actually). >> >> There are uses like below though, and that would also add some overhead >> on iov_iter_type(), so it's not apparent to me which version would be >> cleaner/faster in the end. But yeah, we can experiment after landing >> this patch. >> >> if (type & (ITER_BVEC|ITER_KVEC)) > > There are exactly 3 such places, and all of them would've been just as well > with case ITER_BVEC: case ITER_KVEC: ... in a switch. > > Hmm... I wonder which would work better: > > enum iter_type { > ITER_IOVEC = 0, > ITER_KVEC = 2, > ITER_BVEC = 4, > ITER_PIPE = 6, > ITER_DISCARD = 8, > }; > iov_iter_type(iter) (((iter)->type) & ~1) > iov_iter_rw(iter) (((iter)->type) & 1) > > or > > enum iter_type { > ITER_IOVEC, > ITER_KVEC, > ITER_BVEC, > ITER_PIPE, > ITER_DISCARD, > }; > iov_iter_type(iter) (((iter)->type) & (~0U>>1)) > // callers of iov_iter_rw() are almost all comparing with explicit READ or WRITE > iov_iter_rw(iter) (((iter)->type) & ~(~0U>>1) ? WRITE : READ) > with places like iov_iter_kvec() doing > i->type = ITER_KVEC | ((direction == WRITE) ? BIT(31) : 0); > > Preferences? For the bitmask version (with this patch) we have most of iov_iter_type() completely optimised out. E.g. identical iov_iter_type(i) & ITER_IOVEC <=> iter->type & ITER_IOVEC It's also nice to have iov_iter_rw() to be just (type & 1), operations with which can be optimised in a handful of ways. Unless the compiler would be able to heavily optimise switches, e.g. to out-of-memory/calculation-based jump tables, that I doubt, I'd personally leave it be. Though, not like it should matter much. -- Pavel Begunkov