* Re: Please stop using iopl() in DPDK
@ 2019-10-25 6:42 ` Willy Tarreau
0 siblings, 0 replies; 17+ messages in thread
From: Willy Tarreau @ 2019-10-25 6:42 UTC (permalink / raw)
To: Andy Lutomirski; +Cc: dev, Thomas Gleixner, Peter Zijlstra, LKML
Hi Andy,
On Thu, Oct 24, 2019 at 09:45:56PM -0700, Andy Lutomirski wrote:
> Hi all-
>
> Supporting iopl() in the Linux kernel is becoming a maintainability
> problem. As far as I know, DPDK is the only major modern user of
> iopl().
>
> After doing some research, DPDK uses direct io port access for only a
> single purpose: accessing legacy virtio configuration structures.
> These structures are mapped in IO space in BAR 0 on legacy virtio
> devices.
>
> There are at least three ways you could avoid using iopl(). Here they
> are in rough order of quality in my opinion:
(...)
I'm just wondering, why wouldn't we introduce a sys_ioport() syscall
to perform I/Os in the kernel without having to play at all with iopl()/
ioperm() ? That would alleviate the need for these large port maps.
Applications that use outb/inb() usually don't need extreme speeds.
Each time I had to use them, it was to access a watchdog, a sensor, a
fan, control a front panel LED, or read/write to NVRAM. Some userland
drivers possibly don't need much more, and very likely run with
privileges turned on all the time, so replacing their inb()/outb() calls
would mostly be a matter of redefining them using a macro to use the
syscall instead.
I'd see an API more or less like this :
int ioport(int op, u16 port, long val, long *ret);
<op> would take values such as INB,INW,INL to fill *<ret>, OUTB,OUTW,OUL
to read from <val>, possibly ORB,ORW,ORL to read, or with <val>, write
back and return previous value to <ret>, ANDB/W/L, XORB/W/L to do the
same with and/xor, and maybe a TEST operation to just validate support
at start time and replace ioperm/iopl so that subsequent calls do not
need to check for errors. Applications could then replace :
ioperm() with ioport(TEST,port,0,0)
iopl() with ioport(TEST,0,0,0)
outb() with ioport(OUTB,port,val,0)
inb() with ({ char val;ioport(INB,port,0,&val);val;})
... and so on.
And then ioperm/iopl can easily be dropped.
Maybe I'm overlooking something ?
Willy
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [dpdk-dev] Please stop using iopl() in DPDK
2019-10-25 6:42 ` Willy Tarreau
@ 2019-10-25 14:45 ` Andy Lutomirski
-1 siblings, 0 replies; 17+ messages in thread
From: Andy Lutomirski @ 2019-10-25 14:45 UTC (permalink / raw)
To: Willy Tarreau; +Cc: Andy Lutomirski, dev, Thomas Gleixner, Peter Zijlstra, LKML
On Thu, Oct 24, 2019 at 11:42 PM Willy Tarreau <w@1wt.eu> wrote:
>
> Hi Andy,
>
> On Thu, Oct 24, 2019 at 09:45:56PM -0700, Andy Lutomirski wrote:
> > Hi all-
> >
> > Supporting iopl() in the Linux kernel is becoming a maintainability
> > problem. As far as I know, DPDK is the only major modern user of
> > iopl().
> >
> > After doing some research, DPDK uses direct io port access for only a
> > single purpose: accessing legacy virtio configuration structures.
> > These structures are mapped in IO space in BAR 0 on legacy virtio
> > devices.
> >
> > There are at least three ways you could avoid using iopl(). Here they
> > are in rough order of quality in my opinion:
> (...)
>
> I'm just wondering, why wouldn't we introduce a sys_ioport() syscall
> to perform I/Os in the kernel without having to play at all with iopl()/
> ioperm() ? That would alleviate the need for these large port maps.
> Applications that use outb/inb() usually don't need extreme speeds.
> Each time I had to use them, it was to access a watchdog, a sensor, a
> fan, control a front panel LED, or read/write to NVRAM. Some userland
> drivers possibly don't need much more, and very likely run with
> privileges turned on all the time, so replacing their inb()/outb() calls
> would mostly be a matter of redefining them using a macro to use the
> syscall instead.
>
> I'd see an API more or less like this :
>
> int ioport(int op, u16 port, long val, long *ret);
Hmm. I have some memory of a /dev/ioport or similar, but now I can't
find it. It does seem quite reasonable.
But, for uses like DPDK, /sys/.../resource0 seems like a *far* better
API, since it actually uses the kernel's concept of which io range
corresponds to which device instead of hoping that the mappings don't
change out from under user code. And it has the added benefit that
it's restricted to a single device.
--Andy
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Please stop using iopl() in DPDK
@ 2019-10-25 14:45 ` Andy Lutomirski
0 siblings, 0 replies; 17+ messages in thread
From: Andy Lutomirski @ 2019-10-25 14:45 UTC (permalink / raw)
To: Willy Tarreau; +Cc: Andy Lutomirski, dev, Thomas Gleixner, Peter Zijlstra, LKML
On Thu, Oct 24, 2019 at 11:42 PM Willy Tarreau <w@1wt.eu> wrote:
>
> Hi Andy,
>
> On Thu, Oct 24, 2019 at 09:45:56PM -0700, Andy Lutomirski wrote:
> > Hi all-
> >
> > Supporting iopl() in the Linux kernel is becoming a maintainability
> > problem. As far as I know, DPDK is the only major modern user of
> > iopl().
> >
> > After doing some research, DPDK uses direct io port access for only a
> > single purpose: accessing legacy virtio configuration structures.
> > These structures are mapped in IO space in BAR 0 on legacy virtio
> > devices.
> >
> > There are at least three ways you could avoid using iopl(). Here they
> > are in rough order of quality in my opinion:
> (...)
>
> I'm just wondering, why wouldn't we introduce a sys_ioport() syscall
> to perform I/Os in the kernel without having to play at all with iopl()/
> ioperm() ? That would alleviate the need for these large port maps.
> Applications that use outb/inb() usually don't need extreme speeds.
> Each time I had to use them, it was to access a watchdog, a sensor, a
> fan, control a front panel LED, or read/write to NVRAM. Some userland
> drivers possibly don't need much more, and very likely run with
> privileges turned on all the time, so replacing their inb()/outb() calls
> would mostly be a matter of redefining them using a macro to use the
> syscall instead.
>
> I'd see an API more or less like this :
>
> int ioport(int op, u16 port, long val, long *ret);
Hmm. I have some memory of a /dev/ioport or similar, but now I can't
find it. It does seem quite reasonable.
But, for uses like DPDK, /sys/.../resource0 seems like a *far* better
API, since it actually uses the kernel's concept of which io range
corresponds to which device instead of hoping that the mappings don't
change out from under user code. And it has the added benefit that
it's restricted to a single device.
--Andy
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] Please stop using iopl() in DPDK
2019-10-25 14:45 ` Andy Lutomirski
@ 2019-10-25 15:03 ` Willy Tarreau
-1 siblings, 0 replies; 17+ messages in thread
From: Willy Tarreau @ 2019-10-25 15:03 UTC (permalink / raw)
To: Andy Lutomirski; +Cc: dev, Thomas Gleixner, Peter Zijlstra, LKML
On Fri, Oct 25, 2019 at 07:45:47AM -0700, Andy Lutomirski wrote:
> But, for uses like DPDK, /sys/.../resource0 seems like a *far* better
> API, since it actually uses the kernel's concept of which io range
> corresponds to which device instead of hoping that the mappings don't
> change out from under user code. And it has the added benefit that
> it's restricted to a single device.
For certain such uses with real device management, very likely yes.
It's just that in a number of programs using hard-coded ports to
access stupid devices with no driver (and often even no name), such
an approach could be overkill, and these are typically the annoyingly
itchy ones which could require your config entry to remain enabled.
I'll add to my todo list to have a look at this as time permits.
Cheers,
Willy
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Please stop using iopl() in DPDK
@ 2019-10-25 15:03 ` Willy Tarreau
0 siblings, 0 replies; 17+ messages in thread
From: Willy Tarreau @ 2019-10-25 15:03 UTC (permalink / raw)
To: Andy Lutomirski; +Cc: dev, Thomas Gleixner, Peter Zijlstra, LKML
On Fri, Oct 25, 2019 at 07:45:47AM -0700, Andy Lutomirski wrote:
> But, for uses like DPDK, /sys/.../resource0 seems like a *far* better
> API, since it actually uses the kernel's concept of which io range
> corresponds to which device instead of hoping that the mappings don't
> change out from under user code. And it has the added benefit that
> it's restricted to a single device.
For certain such uses with real device management, very likely yes.
It's just that in a number of programs using hard-coded ports to
access stupid devices with no driver (and often even no name), such
an approach could be overkill, and these are typically the annoyingly
itchy ones which could require your config entry to remain enabled.
I'll add to my todo list to have a look at this as time permits.
Cheers,
Willy
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] Please stop using iopl() in DPDK
2019-10-25 14:45 ` Andy Lutomirski
@ 2019-10-27 23:44 ` Maciej W. Rozycki
-1 siblings, 0 replies; 17+ messages in thread
From: Maciej W. Rozycki @ 2019-10-27 23:44 UTC (permalink / raw)
To: Andy Lutomirski; +Cc: Willy Tarreau, dev, Thomas Gleixner, Peter Zijlstra, LKML
On Fri, 25 Oct 2019, Andy Lutomirski wrote:
> > I'd see an API more or less like this :
> >
> > int ioport(int op, u16 port, long val, long *ret);
>
> Hmm. I have some memory of a /dev/ioport or similar, but now I can't
> find it. It does seem quite reasonable.
crw-r----- 1 root kmem 1, 4 Sep 9 13:58 /dev/port
Maciej
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Please stop using iopl() in DPDK
@ 2019-10-27 23:44 ` Maciej W. Rozycki
0 siblings, 0 replies; 17+ messages in thread
From: Maciej W. Rozycki @ 2019-10-27 23:44 UTC (permalink / raw)
To: Andy Lutomirski; +Cc: Willy Tarreau, dev, Thomas Gleixner, Peter Zijlstra, LKML
On Fri, 25 Oct 2019, Andy Lutomirski wrote:
> > I'd see an API more or less like this :
> >
> > int ioport(int op, u16 port, long val, long *ret);
>
> Hmm. I have some memory of a /dev/ioport or similar, but now I can't
> find it. It does seem quite reasonable.
crw-r----- 1 root kmem 1, 4 Sep 9 13:58 /dev/port
Maciej
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] Please stop using iopl() in DPDK
2019-10-25 6:42 ` Willy Tarreau
(?)
(?)
@ 2019-10-28 16:42 ` Stephen Hemminger
2019-10-28 18:00 ` Andy Lutomirski
2019-10-28 20:13 ` Willy Tarreau
-1 siblings, 2 replies; 17+ messages in thread
From: Stephen Hemminger @ 2019-10-28 16:42 UTC (permalink / raw)
To: Willy Tarreau; +Cc: Andy Lutomirski, dev, Thomas Gleixner, Peter Zijlstra, LKML
On Fri, 25 Oct 2019 08:42:25 +0200
Willy Tarreau <w@1wt.eu> wrote:
> Hi Andy,
>
> On Thu, Oct 24, 2019 at 09:45:56PM -0700, Andy Lutomirski wrote:
> > Hi all-
> >
> > Supporting iopl() in the Linux kernel is becoming a maintainability
> > problem. As far as I know, DPDK is the only major modern user of
> > iopl().
> >
> > After doing some research, DPDK uses direct io port access for only a
> > single purpose: accessing legacy virtio configuration structures.
> > These structures are mapped in IO space in BAR 0 on legacy virtio
> > devices.
> >
> > There are at least three ways you could avoid using iopl(). Here they
> > are in rough order of quality in my opinion:
> (...)
>
> I'm just wondering, why wouldn't we introduce a sys_ioport() syscall
> to perform I/Os in the kernel without having to play at all with iopl()/
> ioperm() ? That would alleviate the need for these large port maps.
> Applications that use outb/inb() usually don't need extreme speeds.
> Each time I had to use them, it was to access a watchdog, a sensor, a
> fan, control a front panel LED, or read/write to NVRAM. Some userland
> drivers possibly don't need much more, and very likely run with
> privileges turned on all the time, so replacing their inb()/outb() calls
> would mostly be a matter of redefining them using a macro to use the
> syscall instead.
>
> I'd see an API more or less like this :
>
> int ioport(int op, u16 port, long val, long *ret);
>
> <op> would take values such as INB,INW,INL to fill *<ret>, OUTB,OUTW,OUL
> to read from <val>, possibly ORB,ORW,ORL to read, or with <val>, write
> back and return previous value to <ret>, ANDB/W/L, XORB/W/L to do the
> same with and/xor, and maybe a TEST operation to just validate support
> at start time and replace ioperm/iopl so that subsequent calls do not
> need to check for errors. Applications could then replace :
>
> ioperm() with ioport(TEST,port,0,0)
> iopl() with ioport(TEST,0,0,0)
> outb() with ioport(OUTB,port,val,0)
> inb() with ({ char val;ioport(INB,port,0,&val);val;})
>
> ... and so on.
>
> And then ioperm/iopl can easily be dropped.
>
> Maybe I'm overlooking something ?
> Willy
DPDK does not want to system calls. It kills performance.
With pure user mode access it can reach > 10 Million Packets/sec
with a system call per packet that drops to 1 Million Packets/sec.
Also, adding new system calls might help in the long term,
but users are often kernels that are at least 5 years behind
upstream.
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [dpdk-dev] Please stop using iopl() in DPDK
2019-10-28 16:42 ` [dpdk-dev] " Stephen Hemminger
@ 2019-10-28 18:00 ` Andy Lutomirski
2019-10-28 20:13 ` Willy Tarreau
1 sibling, 0 replies; 17+ messages in thread
From: Andy Lutomirski @ 2019-10-28 18:00 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Willy Tarreau, Andy Lutomirski, dev, Thomas Gleixner,
Peter Zijlstra, LKML
> On Oct 28, 2019, at 10:43 AM, Stephen Hemminger <stephen@networkplumber.org> wrote:
>
> On Fri, 25 Oct 2019 08:42:25 +0200
> Willy Tarreau <w@1wt.eu> wrote:
>
>> Hi Andy,
>>
>>> On Thu, Oct 24, 2019 at 09:45:56PM -0700, Andy Lutomirski wrote:
>>> Hi all-
>>>
>>> Supporting iopl() in the Linux kernel is becoming a maintainability
>>> problem. As far as I know, DPDK is the only major modern user of
>>> iopl().
>>>
>>> After doing some research, DPDK uses direct io port access for only a
>>> single purpose: accessing legacy virtio configuration structures.
>>> These structures are mapped in IO space in BAR 0 on legacy virtio
>>> devices.
>>>
>>> There are at least three ways you could avoid using iopl(). Here they
>>> are in rough order of quality in my opinion:
>> (...)
>>
>> I'm just wondering, why wouldn't we introduce a sys_ioport() syscall
>> to perform I/Os in the kernel without having to play at all with iopl()/
>> ioperm() ? That would alleviate the need for these large port maps.
>> Applications that use outb/inb() usually don't need extreme speeds.
>> Each time I had to use them, it was to access a watchdog, a sensor, a
>> fan, control a front panel LED, or read/write to NVRAM. Some userland
>> drivers possibly don't need much more, and very likely run with
>> privileges turned on all the time, so replacing their inb()/outb() calls
>> would mostly be a matter of redefining them using a macro to use the
>> syscall instead.
>>
>> I'd see an API more or less like this :
>>
>> int ioport(int op, u16 port, long val, long *ret);
>>
>> <op> would take values such as INB,INW,INL to fill *<ret>, OUTB,OUTW,OUL
>> to read from <val>, possibly ORB,ORW,ORL to read, or with <val>, write
>> back and return previous value to <ret>, ANDB/W/L, XORB/W/L to do the
>> same with and/xor, and maybe a TEST operation to just validate support
>> at start time and replace ioperm/iopl so that subsequent calls do not
>> need to check for errors. Applications could then replace :
>>
>> ioperm() with ioport(TEST,port,0,0)
>> iopl() with ioport(TEST,0,0,0)
>> outb() with ioport(OUTB,port,val,0)
>> inb() with ({ char val;ioport(INB,port,0,&val);val;})
>>
>> ... and so on.
>>
>> And then ioperm/iopl can easily be dropped.
>>
>> Maybe I'm overlooking something ?
>> Willy
>
> DPDK does not want to system calls. It kills performance.
> With pure user mode access it can reach > 10 Million Packets/sec
> with a system call per packet that drops to 1 Million Packets/sec.
If you are getting 10 MPPS with an OUT per packet, I’ll buy you a
whole case of beer.
I’m suggesting that, on virtio-legacy, you benchmark the performance
hit of using a syscall to ring the doorbell. Right now, you're doing
an OUT instruction that traps to the hypervisor, probably gets
emulated, and goes out to whatever host-side driver is running. The
cost of doing that is going to be quite high, especially on older
machines. I'm guessing that adding a syscall to the mix won't make
much difference.
--Andy
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [dpdk-dev] Please stop using iopl() in DPDK
2019-10-28 16:42 ` [dpdk-dev] " Stephen Hemminger
2019-10-28 18:00 ` Andy Lutomirski
@ 2019-10-28 20:13 ` Willy Tarreau
1 sibling, 0 replies; 17+ messages in thread
From: Willy Tarreau @ 2019-10-28 20:13 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Andy Lutomirski, dev, Thomas Gleixner, Peter Zijlstra, LKML
Hi Stephen,
On Mon, Oct 28, 2019 at 09:42:53AM -0700, Stephen Hemminger wrote:
(...)
> > I'd see an API more or less like this :
> >
> > int ioport(int op, u16 port, long val, long *ret);
> >
> > <op> would take values such as INB,INW,INL to fill *<ret>, OUTB,OUTW,OUL
> > to read from <val>, possibly ORB,ORW,ORL to read, or with <val>, write
> > back and return previous value to <ret>, ANDB/W/L, XORB/W/L to do the
> > same with and/xor, and maybe a TEST operation to just validate support
> > at start time and replace ioperm/iopl so that subsequent calls do not
> > need to check for errors. Applications could then replace :
> >
> > ioperm() with ioport(TEST,port,0,0)
> > iopl() with ioport(TEST,0,0,0)
> > outb() with ioport(OUTB,port,val,0)
> > inb() with ({ char val;ioport(INB,port,0,&val);val;})
> >
> > ... and so on.
> >
> > And then ioperm/iopl can easily be dropped.
> >
> > Maybe I'm overlooking something ?
> > Willy
>
> DPDK does not want to system calls. It kills performance.
> With pure user mode access it can reach > 10 Million Packets/sec
> with a system call per packet that drops to 1 Million Packets/sec.
I know that it would cause this on the data path, but are you *really*
sure that in/out calls are performed there, because these are terribly
slow already ? I'd suspect that instead it's relying on read/write of
memory-mapped registers and descriptors. I really suspect that I/Os
are only used for configuration purposes, which is why I proposed the
stuff above (otherwise I obviously agree that syscalls in the data
path are performance killers).
> Also, adding new system calls might help in the long term,
> but users are often kernels that are at least 5 years behind
> upstream.
Sure but that has never been really an issue, what matters is that
backwards compatibility is long enough to let old features smoothly
fade away. Some people make fun of me because I still care a bit
about kernel 2.4 and openssl 0.9.7 compatibility for haproxy, so
yes, I am careful about backwards compatibility and smooth upgrades ;-)
Willy
^ permalink raw reply [flat|nested] 17+ messages in thread