Thread (50 messages) 50 messages, 9 authors, 2017-01-20

Re: [LSF/MM TOPIC][LSF/MM ATTEND] NAPI polling for block drivers

From: Andrey Kuzmin <hidden>
Date: 2017-01-17 16:44:38

On Tue, Jan 17, 2017 at 6:38 PM, Sagi Grimberg [off-list ref] wrote:
Hey, so I made some initial analysis of whats going on with
irq-poll.

First, I sampled how much time it takes before we
get the interrupt in nvme_irq and the initial visit
to nvme_irqpoll_handler. I ran a single threaded fio
with QD=32 of 4K reads. This is two displays of a
histogram of the latency (ns):
--
[1]
queue = b'nvme0q1'
     usecs               : count     distribution
         0 -> 1          : 7310 |****************************************|
         2 -> 3          : 11       |      |
         4 -> 7          : 10       |      |
         8 -> 15         : 20       |      |
        16 -> 31         : 0        |      |
        32 -> 63         : 0        |      |
        64 -> 127        : 1        |      |

[2]
queue = b'nvme0q1'
     usecs               : count     distribution
         0 -> 1          : 7309 |****************************************|
         2 -> 3          : 14       |      |
         4 -> 7          : 7        |      |
         8 -> 15         : 17       |      |

We can see that most of the time our latency is pretty good (<1ns) but with
huge tail latencies (some 8-15 ns and even one in 32-63 ns).
**NOTE, in order to reduce the tracing impact on performance I sampled
for every 100 interrupts.

I also sampled for a multiple threads/queues with QD=32 of 4K reads.
This is a collection of histograms for 5 queues (5 fio threads):
queue = b'nvme0q1'
     usecs               : count     distribution
         0 -> 1          : 701 |****************************************|
         2 -> 3          : 177      |**********      |
         4 -> 7          : 56       |***      |
         8 -> 15         : 24       |*      |
        16 -> 31         : 6        |      |
        32 -> 63         : 1        |      |

queue = b'nvme0q2'
     usecs               : count     distribution
         0 -> 1          : 412 |****************************************|
         2 -> 3          : 52       |*****      |
         4 -> 7          : 19       |*      |
         8 -> 15         : 13       |*      |
        16 -> 31         : 5        |      |

queue = b'nvme0q3'
     usecs               : count     distribution
         0 -> 1          : 381 |****************************************|
         2 -> 3          : 74       |*******      |
         4 -> 7          : 26       |**      |
         8 -> 15         : 12       |*      |
        16 -> 31         : 3        |      |
        32 -> 63         : 0        |      |
        64 -> 127        : 0        |      |
       128 -> 255        : 1        |      |

queue = b'nvme0q4'
     usecs               : count     distribution
         0 -> 1          : 386 |****************************************|
         2 -> 3          : 63       |******      |
         4 -> 7          : 30       |***      |
         8 -> 15         : 11       |*      |
        16 -> 31         : 7        |      |
        32 -> 63         : 1        |      |

queue = b'nvme0q5'
     usecs               : count     distribution
         0 -> 1          : 384 |****************************************|
         2 -> 3          : 69       |*******      |
         4 -> 7          : 25       |**      |
         8 -> 15         : 15       |*      |
        16 -> 31         : 3        |      |

Overall looks pretty much the same but some more samples with tails...

Next, I sampled how many completions we are able to consume per interrupt.
Two exaples of histograms of how many completions we take per interrupt.
--
queue = b'nvme0q1'
     completed     : count     distribution
        0          : 0        |                                        |
        1          : 11690    |****************************************|
        2          : 46       |                                        |
        3          : 1        |                                        |

queue = b'nvme0q1'
     completed     : count     distribution
        0          : 0        |                                        |
        1          : 944      |****************************************|
        2          : 8        |                                        |
--

So it looks like we are super not efficient because most of the times we
catch 1
completion per interrupt and the whole point is that we need to find more!
This fio
is single threaded with QD=32 so I'd expect that we be somewhere in 8-31
almost all
the time... I also tried QD=1024, histogram is still the same.
It looks like it takes you longer to submit an I/O than to service an
interrupt, so increasing queue depth in the singe-threaded case doesn't
make much difference. You might want to try multiple threads per core with
QD, say, 32 (but beware that Intel limits the aggregate queue depth to 256
and even 128 for some models).

Regards,
Andrey



**NOTE: Here I also sampled for every 100 interrupts.


I'll try to run the counter on the current nvme driver and see what I get.



I attached the bpf scripts I wrote (nvme-trace-irq, nvme-count-comps)
with hope that someone is interested enough to try and reproduce these
numbers on his/hers setup and maybe suggest some other useful tracing
we can do.

Prerequisites:
1. iovisor is needed for python bpf support.
  $ echo "deb [trusted=yes] https://repo.iovisor.org/apt/xenial
xenial-nightly main" | sudo tee /etc/apt/sources.list.d/iovisor.list
  $ sudo apt-get update -y
  $ sudo apt-get install bcc-tools -y
  # Nastty hack .. bcc only available in python2 but copliant with
python3..
  $ sudo cp -r /usr/lib/python2.7/dist-packages/bcc
/usr/lib/python3/dist-packages/

2. Because we don't have the nvme-pci symbols exported, The nvme.h file is
needed on the
   test machine (where the bpf code is running). I used nfs mount for the
linux source (this
   is why I include from /mnt/linux in the scripts).


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help