You can subscribe to this list here.
1999 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(8) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2000 |
Jan
(19) |
Feb
(11) |
Mar
(56) |
Apr
(31) |
May
(37) |
Jun
(21) |
Jul
(30) |
Aug
(31) |
Sep
(25) |
Oct
(60) |
Nov
(28) |
Dec
(57) |
2001 |
Jan
(47) |
Feb
(119) |
Mar
(279) |
Apr
(198) |
May
(336) |
Jun
(201) |
Jul
(136) |
Aug
(123) |
Sep
(123) |
Oct
(185) |
Nov
(66) |
Dec
(97) |
2002 |
Jan
(318) |
Feb
(101) |
Mar
(167) |
Apr
(233) |
May
(249) |
Jun
(134) |
Jul
(195) |
Aug
(99) |
Sep
(278) |
Oct
(435) |
Nov
(326) |
Dec
(325) |
2003 |
Jan
(214) |
Feb
(309) |
Mar
(142) |
Apr
(141) |
May
(210) |
Jun
(86) |
Jul
(133) |
Aug
(218) |
Sep
(315) |
Oct
(152) |
Nov
(162) |
Dec
(288) |
2004 |
Jan
(277) |
Feb
(267) |
Mar
(182) |
Apr
(168) |
May
(254) |
Jun
(131) |
Jul
(168) |
Aug
(177) |
Sep
(262) |
Oct
(309) |
Nov
(262) |
Dec
(255) |
2005 |
Jan
(258) |
Feb
(169) |
Mar
(282) |
Apr
(208) |
May
(262) |
Jun
(187) |
Jul
(207) |
Aug
(171) |
Sep
(283) |
Oct
(216) |
Nov
(307) |
Dec
(107) |
2006 |
Jan
(207) |
Feb
(82) |
Mar
(192) |
Apr
(165) |
May
(121) |
Jun
(108) |
Jul
(120) |
Aug
(126) |
Sep
(101) |
Oct
(216) |
Nov
(95) |
Dec
(125) |
2007 |
Jan
(176) |
Feb
(117) |
Mar
(240) |
Apr
(120) |
May
(81) |
Jun
(82) |
Jul
(62) |
Aug
(120) |
Sep
(103) |
Oct
(109) |
Nov
(181) |
Dec
(87) |
2008 |
Jan
(145) |
Feb
(69) |
Mar
(31) |
Apr
(98) |
May
(91) |
Jun
(43) |
Jul
(68) |
Aug
(135) |
Sep
(48) |
Oct
(18) |
Nov
(29) |
Dec
(16) |
2009 |
Jan
(26) |
Feb
(15) |
Mar
(83) |
Apr
(39) |
May
(23) |
Jun
(35) |
Jul
(11) |
Aug
(3) |
Sep
(11) |
Oct
(2) |
Nov
(28) |
Dec
(8) |
2010 |
Jan
(4) |
Feb
(40) |
Mar
(4) |
Apr
(46) |
May
(35) |
Jun
(46) |
Jul
(10) |
Aug
(4) |
Sep
(50) |
Oct
(70) |
Nov
(31) |
Dec
(24) |
2011 |
Jan
(17) |
Feb
(8) |
Mar
(35) |
Apr
(50) |
May
(75) |
Jun
(55) |
Jul
(72) |
Aug
(272) |
Sep
(10) |
Oct
(9) |
Nov
(11) |
Dec
(15) |
2012 |
Jan
(36) |
Feb
(49) |
Mar
(54) |
Apr
(47) |
May
(8) |
Jun
(82) |
Jul
(20) |
Aug
(50) |
Sep
(51) |
Oct
(20) |
Nov
(10) |
Dec
(25) |
2013 |
Jan
(34) |
Feb
(4) |
Mar
(24) |
Apr
(40) |
May
(101) |
Jun
(30) |
Jul
(55) |
Aug
(84) |
Sep
(53) |
Oct
(49) |
Nov
(61) |
Dec
(36) |
2014 |
Jan
(26) |
Feb
(22) |
Mar
(30) |
Apr
(4) |
May
(43) |
Jun
(33) |
Jul
(44) |
Aug
(61) |
Sep
(46) |
Oct
(154) |
Nov
(16) |
Dec
(12) |
2015 |
Jan
(18) |
Feb
(2) |
Mar
(122) |
Apr
(23) |
May
(56) |
Jun
(29) |
Jul
(35) |
Aug
(15) |
Sep
|
Oct
(45) |
Nov
(94) |
Dec
(38) |
2016 |
Jan
(50) |
Feb
(39) |
Mar
(39) |
Apr
(1) |
May
(14) |
Jun
(12) |
Jul
(19) |
Aug
(12) |
Sep
(9) |
Oct
(1) |
Nov
(13) |
Dec
(7) |
2017 |
Jan
(6) |
Feb
(1) |
Mar
(16) |
Apr
(5) |
May
(61) |
Jun
(18) |
Jul
(43) |
Aug
(1) |
Sep
(8) |
Oct
(25) |
Nov
(30) |
Dec
(6) |
2018 |
Jan
(5) |
Feb
(2) |
Mar
(25) |
Apr
(15) |
May
(2) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2019 |
Jan
|
Feb
(2) |
Mar
|
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Richard W. <ri...@no...> - 2016-12-16 14:19:40
|
The following changes since commit 69973b830859bc6529a7a0468ba0d80ee5117826: Linux 4.9 (2016-12-11 11:17:54 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml.git for-linus-4.10-rc1 for you to fetch changes up to f88f0bdfc32f3d1e2fd03ec8a7f7b456df4db725: um: UBD Improvements (2016-12-14 22:46:55 +0100) ---------------------------------------------------------------- This pull request contains: * A performance enhancement for UML's block driver ---------------------------------------------------------------- Anton Ivanov (1): um: UBD Improvements arch/um/drivers/ubd.h | 5 ++ arch/um/drivers/ubd_kern.c | 168 ++++++++++++++++++++++++++++++++++++++------- arch/um/drivers/ubd_user.c | 21 +++++- 3 files changed, 167 insertions(+), 27 deletions(-) |
From: Richard W. <ri...@no...> - 2016-12-14 21:55:06
|
Paul, On 08.08.2016 22:35, Paul E. McKenney wrote: > On Mon, Aug 08, 2016 at 10:12:11PM +0200, Richard Weinberger wrote: >> Paul, >> >> Am 15.06.2016 um 14:45 schrieb Paul E. McKenney: >>> On Wed, Jun 15, 2016 at 09:05:37AM +0200, Richard Weinberger wrote: >>>> Paul, >>>> >>>> Am 15.06.2016 um 00:54 schrieb Paul E. McKenney: >>>>> On Mon, Jun 06, 2016 at 02:04:03AM +0800, kbuild test robot wrote: >>>>>> tree: https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next >>>>>> head: 13ee0de9cd2444b57ce30c4f1607b49b90aa0c38 >>>>>> commit: f251ac814fc5787765009e60d54a2bd4277350c8 [25/36] rcu: Make call_rcu_tasks() tolerate first call with irqs disabled >>>>>> config: um-allmodconfig (attached as .config) >>>>>> compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 >>>>>> reproduce: >>>>>> git checkout f251ac814fc5787765009e60d54a2bd4277350c8 >>>>>> # save the attached .config to linux build tree >>>>>> make ARCH=um >>>>> >>>>> My kneejerk reaction would be to make CONFIG_TASKS_RCU depend on >>>>> !UML or something similar. >>>>> >>>>> Another approach would be create a arch_irqs_disabled_flags() for UML. >>>>> >>>>> Any preferences? >>>> >>>> Patches for arch_irqs_disabled_flags() support are already on LKML: >>>> https://lkml.org/lkml/2016/6/12/162 >>>> >>>> My plan was to merge them in the v4.8 merge window. >>>> So having CONFIG_TASKS_RCU depend on !UML for now should be fine. >>>> We can remove the dependency in v4.8 again. >>> >>> Sounds very good, thank you! >> >> The patch is now in Linus' tree. So, you can enable CONFIG_TASKS_RCU >> for UML again. :-) > > Very good, thank you! I have a patch slated for the next merge window. > If you need it sooner, please let me know. Just noticed that CONFIG_TASKS_RCU is still disabled for UML in today's next. Is there something missing in UML? Thanks, //richard |
From: Richard W. <ri...@no...> - 2016-12-12 20:28:53
|
On 12.12.2016 20:10, Ritesh Raj Sarraf wrote: > On Mon, 2016-12-12 at 17:32 +0100, Richard Weinberger wrote: >> Isn't this a toolchain bug? >> Can you please try this fix? >> https://sourceware.org/bugzilla/show_bug.cgi?id=20800 > > Thanks for the link. I think that'd fix the bug but I'll have to wait until 2.28 > hits into Debian. > > There have been lots of build failures, in multiple tools, in Debian with this > global change. And we've been overriding the default build flags for the failing > tools. But for uml, adding the linker flag of -fno-pie did not help. AFAICT this issue is unrelated to Debian's -fpie mess. :-) Thanks, //richard |
From: Ritesh R. S. <rr...@re...> - 2016-12-12 19:28:29
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Mon, 2016-12-12 at 17:32 +0100, Richard Weinberger wrote: > Isn't this a toolchain bug? > Can you please try this fix? > https://sourceware.org/bugzilla/show_bug.cgi?id=20800 Thanks for the link. I think that'd fix the bug but I'll have to wait until 2.28 hits into Debian. There have been lots of build failures, in multiple tools, in Debian with this global change. And we've been overriding the default build flags for the failing tools. But for uml, adding the linker flag of -fno-pie did not help. - -- Ritesh Raj Sarraf RESEARCHUT - http://www.researchut.com "Necessity is the mother of invention." -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEQCVDstmIVAB/Yn02pjpYo/LhdWkFAlhO9iEACgkQpjpYo/Lh dWloEQ/7BbkL6qAmJLAJFCCbODvW+Xhcwqqs9E5PYCC992bvDyOB26G6SJm9UGwX W7lLWTRyJz/L3Txmrjdr0BN5InNDPD3xj3vnzDDWVxQZrIO6Q3W43oT19A39SB30 WwHYPca52ZtIYE0OuTBqJIacNKDzISsYysd36OfPJTFOHW4KogFEdhIDWHEs39rA ATFprtj4+NMNXv0/xFsoz8BIjhRyQEd4jCsXtLO8zgsWKtYmPoF6KuD/LGkz5Ju2 qo6iO4DwJFzyrkc1ZhylhmpMAB3W9noelZvWUFedqjPlNo3cFKT3xw/b+FRRnIz/ ObnGoI2PYr56Q+crSBGqGxuia6vjUOXrn6h63yk0RScqTH3OOnUkfICeZhPPqFvl cotwF6C2M9gVwLR8kIM2BFrC5Zcd5B7V+HD34pvlMMI4s3PAdLDPAesq3l353Mgc lfLnkPb6lGrxcnwpEsk36ur1kuBs8JvdToBrlLjSF3IqJ9deXQzJsgDsSDw41AXH oJ8tcAHx62wOzrsJ4DBI0O45+YxW4dsJHFnWBS3/DGc4LJI9ArtA3f/1AvYYHuKd WWjRKgUmsVa0tybwZUqXBrMv55Diiioab8F/RoQlaLBBq4EvsjrFj+ciNpPCi6UV fD4xkYi+QQDCUCoc1K7LOnXzaUwW43Fvpu2UazEuGj4MmnC4RV0= =oBOm -----END PGP SIGNATURE----- |
From: Richard W. <ric...@gm...> - 2016-12-12 16:32:51
|
Hi! On Sat, Dec 3, 2016 at 7:20 PM, Ritesh Raj Sarraf <rr...@re...> wrote: > Hi, > > On Debian Sid (Unstable), with Linux version 4.8.11, I was hopeful that uml > would build proper with gcc-6. But I still am getting the below mentioned build > failure. > > The 4.8.11 kernel has the fixes for the core kernel. I'm not sure if any extra > changes are needed for UM again. > > The current workaround that we use in Debian to build latest UML bits from the > kernel source, is to use the gcc-5 compiler. > > The Debian bug report is accessible at: > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=837579 > > Thanks, > Ritesh > > > The fix that went in the stable release is: > http://git.kernel.org/cgit/linux/kernel/git/stable/stable-queue.git/commit/?id=a > fad7e0e67ef545a4d92507a236f0666c33d3ad4 > > CC [M] lib/cordic.o > CC [M] lib/asn1_decoder.o > GEN lib/oid_registry_data.c > perl: warning: Setting locale failed. > perl: warning: Please check that your locale settings: > LANGUAGE = "en_IN:en", > LC_ALL = (unset), > LC_TIME = "en_IN.utf8", > LC_MONETARY = "en_IN.utf8", > LC_COLLATE = "C", > LC_MEASUREMENT = "en_IN.utf8", > LC_NUMERIC = "C", > LC_PAPER = "en_IN.utf8", > LANG = "C" > are supported and installed on your system. > perl: warning: Falling back to the standard locale ("C"). > CC [M] lib/oid_registry.o > LD virt/lib/built-in.o > LD virt/built-in.o > LINK vmlinux > LD vmlinux.o > MODPOST vmlinux.o > GEN .version > CHK include/generated/compile.h > UPD include/generated/compile.h > CC init/version.o > LD init/built-in.o > /usr/bin/ld: arch/um/drivers/built-in.o: relocation R_X86_64_32 against > `.rodata.str1.1' can not be used when making a shared object; recompile with > -fPIC > /usr/bin/ld: final link failed: Nonrepresentable section on output > collect2: error: ld returned 1 exit status > Makefile:955: recipe for target 'vmlinux' failed > make[1]: *** [vmlinux] Error 1 > make[1]: Leaving directory '/build/user-mode-linux-4.8-1um/linux-source-4.8' > debian/rules:76: recipe for target 'build-stamp' failed > make: *** [build-stamp] Error 2 > Isn't this a toolchain bug? Can you please try this fix? https://sourceware.org/bugzilla/show_bug.cgi?id=20800 -- Thanks, //richard |
From: Ritesh R. S. <rr...@re...> - 2016-12-03 18:30:17
|
Hi, On Debian Sid (Unstable), with Linux version 4.8.11, I was hopeful that uml would build proper with gcc-6. But I still am getting the below mentioned build failure. The 4.8.11 kernel has the fixes for the core kernel. I'm not sure if any extra changes are needed for UM again. The current workaround that we use in Debian to build latest UML bits from the kernel source, is to use the gcc-5 compiler. The Debian bug report is accessible at: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=837579 Thanks, Ritesh The fix that went in the stable release is: http://git.kernel.org/cgit/linux/kernel/git/stable/stable-queue.git/commit/?id=a fad7e0e67ef545a4d92507a236f0666c33d3ad4 CC [M] lib/cordic.o CC [M] lib/asn1_decoder.o GEN lib/oid_registry_data.c perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = "en_IN:en", LC_ALL = (unset), LC_TIME = "en_IN.utf8", LC_MONETARY = "en_IN.utf8", LC_COLLATE = "C", LC_MEASUREMENT = "en_IN.utf8", LC_NUMERIC = "C", LC_PAPER = "en_IN.utf8", LANG = "C" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C"). CC [M] lib/oid_registry.o LD virt/lib/built-in.o LD virt/built-in.o LINK vmlinux LD vmlinux.o MODPOST vmlinux.o GEN .version CHK include/generated/compile.h UPD include/generated/compile.h CC init/version.o LD init/built-in.o /usr/bin/ld: arch/um/drivers/built-in.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status Makefile:955: recipe for target 'vmlinux' failed make[1]: *** [vmlinux] Error 1 make[1]: Leaving directory '/build/user-mode-linux-4.8-1um/linux-source-4.8' debian/rules:76: recipe for target 'build-stamp' failed make: *** [build-stamp] Error 2 dpkg-buildpackage: error: debian/rules build gave error exit status 2 I: copying local configuration E: Failed autobuilding of package I: unmounting /var/tmp/lxc/ccache/ccache filesystem I: unmounting /var/cache/apt/archives/ filesystem I: unmounting dev/pts filesystem I: unmounting run/shm filesystem I: unmounting proc filesystem I: unmounting sys filesystem I: cleaning the build env I: removing directory /var/tmp/Debian-Build/Build//25270 and its subdirectories 23:15 ♒♒♒ ☹ => 1 rrs@chutzpah:~/Community/Packaging/user-mode-linux (master)$ -- Given the large number of mailing lists I follow, I request you to CC me in replies for quicker response |
From: Richard W. <ri...@no...> - 2016-11-16 14:36:10
|
Keno, On 16.11.2016 04:45, Keno Fischer wrote: > Just as an FYI, the linker bug has been fixed in binutils. Interesting. Is the same bug also the root cause why a static build of UML does not work? Thanks, //richard |
From: Thomas M. <th...@m3...> - 2016-11-12 12:04:43
|
Hi, my kernel log is full with those messages: any ideas? I have CONFIG_LOCKDEP=y set. [ 3237.220000] ------------[ cut here ]------------ [ 3237.220000] WARNING: CPU: 0 PID: 1445 at mm/mmap.c:1110 vma_merge+0x323/0x3c0 [ 3237.220000] Modules linked in: [ 3237.220000] CPU: 0 PID: 1445 Comm: mdadm Tainted: G W 4.9.0-rc3-00262-g53886f5 #277 [ 3237.220000] Stack: [ 3237.220000] ae8d5a40 600c3024 00000009 00000000 [ 3237.220000] 6014fb9c 00000000 ae8d5a50 604d4aac [ 3237.220000] ae8d5ab0 6006606e 456ae8d5a70 60193b13 [ 3237.220000] Call Trace: [ 3237.220000] [<60193b13>] ? [ 3237.220000] vma_merge+0x323/0x3c0 [<6014fb9c>] ? [ 3237.220000] printk+0x0/0x94 [<60043b29>] [ 3237.220000] show_stack+0x129/0x190 [<600c3024>] ? [ 3237.220000] dump_stack_print_info+0xe4/0xf0 [<6014fb9c>] ? [ 3237.220000] printk+0x0/0x94 [<604d4aac>] [ 3237.220000] dump_stack+0x2a/0x2e [<6006606e>] [ 3237.220000] __warn+0x11e/0x150 [<60193b13>] ? [ 3237.220000] vma_merge+0x323/0x3c0 [<607fa224>] ? [ 3237.220000] _raw_spin_unlock_irqrestore+0x54/0x80 [<600661ef>] [ 3237.220000] warn_slowpath_null+0x1f/0x30 [<60193b13>] [ 3237.220000] vma_merge+0x323/0x3c0 [<601951f0>] ? [ 3237.220000] may_expand_vm+0x0/0x170 [<6019783d>] [ 3237.220000] mprotect_fixup+0x14d/0x2e0 [<601cb87c>] [ 3237.220000] setup_arg_pages+0x10c/0x470 [<6023f3d5>] [ 3237.220000] load_elf_binary+0x475/0xfa0 [<6005a288>] ? [ 3237.220000] set_signals+0x28/0x50 [<600b7be6>] ? [ 3237.220000] lock_release+0x736/0x7f0 [<600b7463>] ? [ 3237.220000] lock_acquire+0x203/0x250 [<600b1e2e>] ? [ 3237.220000] lock_acquired+0x4ae/0x530 [<601ccfb4>] ? [ 3237.220000] search_binary_handler+0xa4/0x290 [<600e98a0>] ? [ 3237.220000] try_module_get+0x0/0x1d0 [<600e98a0>] ? [ 3237.220000] try_module_get+0x0/0x1d0 [<601ccf9b>] [ 3237.220000] search_binary_handler+0x8b/0x290 [<6008ecf5>] ? [ 3237.220000] __task_pid_nr_ns+0x225/0x240 [<600c8b90>] ? [ 3237.220000] debug_lockdep_rcu_enabled+0x0/0x40 [<601cb220>] ? [ 3237.220000] copy_strings+0x0/0x500 [<600c8b90>] ? [ 3237.220000] debug_lockdep_rcu_enabled+0x0/0x40 [<6043a658>] [ 3237.220000] exec_binprm+0x18c/0x364 [<601cb220>] ? [ 3237.220000] copy_strings+0x0/0x500 [<601cde98>] [ 3237.220000] do_execveat_common+0x6d8/0x8c0 [<601ce436>] [ 3237.220000] SyS_execve+0x36/0x40 [<60046288>] [ 3237.220000] handle_syscall+0x98/0xc0 [<6005d662>] [ 3237.220000] userspace+0x3c2/0x4d0 [<60058c1f>] ? [ 3237.220000] save_registers+0x1f/0x50 [<60060c77>] ? [ 3237.220000] arch_prctl+0x117/0x1e0 [<600422e5>] [ 3237.220000] fork_handler+0x85/0x90 [ 3237.220000] [ 3237.220000] ---[ end trace 3d18ccfe26aa207a ]--- [ 3237.270000] reboot: System halted with kind regards thomas |
From: Richard W. <ri...@no...> - 2016-11-11 22:07:54
|
On 11.11.2016 22:03, Keno Fischer wrote: > Did you have CONFIG_INET set? I'm attaching my full .config. This is > on vanilla Ubuntu 16.10. Yes, CONFIG_INET is set. Let my try on Ubuntu. ;-\ > I did see the same error when building with `CONFIG_STATIC_LINK=y`. > Note that I also, separately, ran into a linker problem, though I > believe it is unrelated to this patch > (though perhaps is related to the problem you're seeing?): > https://sourceware.org/bugzilla/show_bug.cgi?id=20800. This seems to be an UML<->glibc issue. memmove() is now an ifunc and for whatever reason it does not work with UML. > I'd also be happy to provide you with ssh access to the machine that > I'm seeing this on if that > would be helpful. Okay, let me try myself first. I think I'm able to install Ubuntu. :) Thanks, //richard |
From: Richard W. <ri...@no...> - 2016-11-11 10:35:09
|
Keno, On 10.11.2016 02:53, Keno Fischer wrote: > Fixes the following link error: > ``` > /usr/bin/ld: net/built-in.o: relocation R_X86_64_32S against `.text' > can not be used when making a shared object; recompile with -fPIC > ``` How and where do you trigger this? I had a chat with Sebastian and we are not 100% sure what is going on. On my freshly installed Debian sid with gcc version 6.2.0 20161109 (Debian 6.2.0-13) UML builds fine except when I set CONFIG_STATIC_LINK=y But then I'm facing a slightly different error: CC init/version.o LD init/built-in.o /usr/bin/ld: init/built-in.o: relocation R_X86_64_PLTOFF64 against STT_GNU_IFUNC symbol `memmove' isn't supported /usr/bin/ld: final link failed: Bad value collect2: error: ld returned 1 exit status Your patch also does not cure this. I'll investigate later into that. > This is the same definition used on some other architectures. > > Signed-off-by: Keno Fischer <ke...@ju...> > --- > I am not sure this is the correct patch in the context of uml. I believe this > should give the runtime ip, which may be different between runs. It may be > better to use the offset in .text (e.g. by using `pc-__text_start`), which > should be consistent. > > arch/x86/um/asm/processor_64.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/x86/um/asm/processor_64.h b/arch/x86/um/asm/processor_64.h > index c3be852..6ca3304 100644 > --- a/arch/x86/um/asm/processor_64.h > +++ b/arch/x86/um/asm/processor_64.h > @@ -32,7 +32,7 @@ static inline void arch_copy_thread(struct arch_thread *from, > } > > #define current_text_addr() \ > - ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) > + ({ __label__ _l; _l: &&_l; }) > > #define current_sp() ({ void *sp; __asm__("movq %%rsp, %0" : "=r" (sp) : ); sp; }) > #define current_bp() ({ unsigned long bp; __asm__("movq %%rbp, %0" : "=r" (bp) : ); bp; }) Thanks, //richard |
From: Richard W. <ri...@no...> - 2016-11-10 20:19:27
|
Keno, On 10.11.2016 21:14, Keno Fischer wrote: > Yes Can you please reply to Sebastian's patch series and explain him how you trigger that error? I don't have a gcc broken by Debian on my machine right now. > On Thu, Nov 10, 2016 at 3:14 PM, Richard Weinberger <ri...@no...> wrote: >> Keno, >> >> On 10.11.2016 21:10, Keno Fischer wrote: >>>> The problem is ready being solved in a generic way: >>>> http://marc.info/?l=linux-kernel&m=147828481602561&w=2 >>>> >>>> Can you please give this patch a try? >>> >>> No dice. After backing out my patch and applying that one I get: >>> >>> /usr/bin/ld: error: net/built-in.o: requires unsupported dynamic reloc >>> 11; recompile with -fPIC >> >> But you applied the whole series, right? Thanks, //richard |
From: Richard W. <ri...@no...> - 2016-11-10 20:14:15
|
Keno, On 10.11.2016 21:10, Keno Fischer wrote: >> The problem is ready being solved in a generic way: >> http://marc.info/?l=linux-kernel&m=147828481602561&w=2 >> >> Can you please give this patch a try? > > No dice. After backing out my patch and applying that one I get: > > /usr/bin/ld: error: net/built-in.o: requires unsupported dynamic reloc > 11; recompile with -fPIC But you applied the whole series, right? Thanks, //richard |
From: Richard W. <ri...@no...> - 2016-11-10 08:05:59
|
Keno, On 10.11.2016 02:53, Keno Fischer wrote: > Fixes the following link error: > ``` > /usr/bin/ld: net/built-in.o: relocation R_X86_64_32S against `.text' > can not be used when making a shared object; recompile with -fPIC > ``` > > This is the same definition used on some other architectures. > > Signed-off-by: Keno Fischer <ke...@ju...> > --- > I am not sure this is the correct patch in the context of uml. I believe this > should give the runtime ip, which may be different between runs. It may be > better to use the offset in .text (e.g. by using `pc-__text_start`), which > should be consistent. The problem is ready being solved in a generic way: http://marc.info/?l=linux-kernel&m=147828481602561&w=2 Can you please give this patch a try? Thanks, //richard |
From: <ant...@ko...> - 2016-11-09 20:43:48
|
From: Anton Ivanov <ai...@ko...> UBD at present is extremely slow because it handles only one request at a time in the IO thread and IRQ handler. The single request at a time is replaced by handling multiple requests as well as necessary workarounds for short reads/writes. Resulting performance improvement in disk IO - 30% Signed-off-by: Anton Ivanov <ai...@ko...> --- arch/um/drivers/ubd.h | 5 ++ arch/um/drivers/ubd_kern.c | 168 ++++++++++++++++++++++++++++++++++++++------- arch/um/drivers/ubd_user.c | 21 +++++- 3 files changed, 167 insertions(+), 27 deletions(-) diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h index 3b48cd2..cc1cc85 100644 --- a/arch/um/drivers/ubd.h +++ b/arch/um/drivers/ubd.h @@ -11,5 +11,10 @@ extern int start_io_thread(unsigned long sp, int *fds_out); extern int io_thread(void *arg); extern int kernel_fd; +extern int ubd_read_poll(int timeout); +extern int ubd_write_poll(int timeout); + +#define UBD_REQ_BUFFER_SIZE 64 + #endif diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f354027..8541027 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015-2016 Anton Ivanov (ai...@br...) * Copyright (C) 2000 Jeff Dike (jd...@ka...) * Licensed under the GPL */ @@ -58,6 +59,17 @@ struct io_thread_req { int error; }; + +static struct io_thread_req * (*irq_req_buffer)[]; +static struct io_thread_req *irq_remainder; +static int irq_remainder_size; + +static struct io_thread_req * (*io_req_buffer)[]; +static struct io_thread_req *io_remainder; +static int io_remainder_size; + + + static inline int ubd_test_bit(__u64 bit, unsigned char *data) { __u64 n; @@ -442,29 +454,91 @@ static void do_ubd_request(struct request_queue * q); static int thread_fd = -1; static LIST_HEAD(restart); -/* XXX - move this inside ubd_intr. */ +/* Function to read several request pointers at a time +* handling fractional reads if (and as) needed +*/ + +static int bulk_req_safe_read( + int fd, + struct io_thread_req * (*request_buffer)[], + struct io_thread_req **remainder, + int *remainder_size, + int max_recs + ) +{ + int n = 0; + int res = 0; + + if (*remainder_size > 0) { + memmove( + (char *) request_buffer, + (char *) remainder, *remainder_size + ); + n = *remainder_size; + } + + res = os_read_file( + fd, + ((char *) request_buffer) + *remainder_size, + sizeof(struct io_thread_req *)*max_recs + - *remainder_size + ); + if (res > 0) { + n += res; + if ((n % sizeof(struct io_thread_req *)) > 0) { + /* + * Read somehow returned not a multiple of dword + * theoretically possible, but never observed in the + * wild, so read routine must be able to handle it + */ + *remainder_size = n % sizeof(struct io_thread_req *); + WARN(*remainder_size > 0, "UBD IPC read returned a partial result"); + memmove( + remainder, + ((char *) request_buffer) + + (n/sizeof(struct io_thread_req *))*sizeof(struct io_thread_req *), + *remainder_size + ); + n = n - *remainder_size; + } + } else { + n = res; + } + return n; +} + /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { - struct io_thread_req *req; struct ubd *ubd; struct list_head *list, *next_ele; unsigned long flags; int n; + int count; while(1){ - n = os_read_file(thread_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(req)){ + n = bulk_req_safe_read( + thread_fd, + irq_req_buffer, + &irq_remainder, + &irq_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if (n < 0) { if(n == -EAGAIN) break; printk(KERN_ERR "spurious interrupt in ubd_handler, " "err = %d\n", -n); return; } - - blk_end_request(req->req, 0, req->length); - kfree(req); + for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { + blk_end_request( + (*irq_req_buffer)[count]->req, + 0, + (*irq_req_buffer)[count]->length + ); + kfree((*irq_req_buffer)[count]); + } } reactivate_fd(thread_fd, UBD_IRQ); @@ -1064,6 +1138,28 @@ static int __init ubd_init(void) if (register_blkdev(fake_major, "ubd")) return -1; } + + irq_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + irq_remainder = 0; + + if (irq_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } + io_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + + io_remainder = 0; + + if (io_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } platform_driver_register(&ubd_driver); mutex_lock(&ubd_lock); for (i = 0; i < MAX_DEV; i++){ @@ -1458,31 +1554,51 @@ static int io_count = 0; int io_thread(void *arg) { - struct io_thread_req *req; - int n; + int n, count, written, res; os_fix_helper_signals(); while(1){ - n = os_read_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)){ - if(n < 0) + n = bulk_req_safe_read( + kernel_fd, + io_req_buffer, + &io_remainder, + &io_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if (n < 0) { + if (n == -EAGAIN) { + ubd_read_poll(-1); + continue; + } else { printk("io_thread - read failed, fd = %d, " - "err = %d\n", kernel_fd, -n); - else { - printk("io_thread - short read, fd = %d, " - "length = %d\n", kernel_fd, n); + "err = %d," + "reminder = %d\n", + kernel_fd, -n, io_remainder_size); } - continue; } - io_count++; - do_io(req); - n = os_write_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)) - printk("io_thread - write failed, fd = %d, err = %d\n", - kernel_fd, -n); + + for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { + io_count++; + do_io((*io_req_buffer)[count]); + } + + written = 0; + + do { + res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n); + if (res > 0) { + written += res; + } else { + if (res != -EAGAIN) { + printk("io_thread - read failed, fd = %d, " + "err = %d\n", kernel_fd, -n); + } + } + if (written < n) { + ubd_write_poll(-1); + } + } while (written < n); } return 0; diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index e376f9b..6f74479 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -1,4 +1,5 @@ -/* +/* + * Copyright (C) 2016 Anton Ivanov (ai...@br...) * Copyright (C) 2000, 2001, 2002 Jeff Dike (jd...@ka...) * Copyright (C) 2001 Ridgerun,Inc (gl...@ri...) * Licensed under the GPL @@ -20,6 +21,9 @@ #include "ubd.h" #include <os.h> +#include <poll.h> + +struct pollfd kernel_pollfd; int start_io_thread(unsigned long sp, int *fd_out) { @@ -32,9 +36,12 @@ int start_io_thread(unsigned long sp, int *fd_out) } kernel_fd = fds[0]; + kernel_pollfd.fd = kernel_fd; + kernel_pollfd.events = POLLIN; *fd_out = fds[1]; err = os_set_fd_block(*fd_out, 0); + err = os_set_fd_block(kernel_fd, 0); if (err) { printk("start_io_thread - failed to set nonblocking I/O.\n"); goto out_close; @@ -57,3 +64,15 @@ int start_io_thread(unsigned long sp, int *fd_out) out: return err; } + +int ubd_read_poll(int timeout) +{ + kernel_pollfd.events = POLLIN; + return poll(&kernel_pollfd, 1, timeout); +} +int ubd_write_poll(int timeout) +{ + kernel_pollfd.events = POLLOUT; + return poll(&kernel_pollfd, 1, timeout); +} + -- 2.1.4 |
From: Anton I. <ant...@ko...> - 2016-11-09 16:21:25
|
On 09/11/16 16:08, James McMechan wrote: > Hi > > I am not clear on the remainder/remainder_size would not a single offset parameter work? rather than copying it off and back? Possible. The other alternative is to copy the remainder (if it exists) to the beginning of the buffer at the end of a read and keep only the offset around instead of keeping two params around. You can no longer reuse the whole read function in both the interrupt handler and the io thread though. The reason is that you can copy the remainder to the beginning of the buffer (so you can use only offset as a single param) only after you have "consumed" all the records. > also max_recs does not seem to used except to calculate max buffer size so would not using a buffer size be easier? > something like bulk_req_read( int fd, struct io_thread_req *buf, size_t len, size_t *offset) > > +static int bulk_req_safe_read( > + int fd, > + struct io_thread_req * (*request_buffer)[], > + struct io_thread_req **remainder, > + int *remainder_size, > + int max_recs > + ) > +{ > + int n = 0; > + int res = 0; > + > + if (*remainder_size > 0) { > + memmove( > + (char *) request_buffer, > + (char *) remainder, *remainder_size > + ); > + n = *remainder_size; > + } > + > + res = os_read_file( > + fd, > + ((char *) request_buffer) + *remainder_size, > + sizeof(struct io_thread_req *)*max_recs > + - *remainder_size > > then here it would be > res = os_read_file(fd, buf+*offset,len-*offset) > Note that if this is ever multithreaded buf and offset or request_buffer/remainder/remainder_size need to be kept separate This is executed only in the single IO thread. > > + ); > + if (res > 0) { > + n += res; > + if ((n % sizeof(struct io_thread_req *)) > 0) { > + /* > + * Read somehow returned not a multiple of dword > + * theoretically possible, but never observed in the > + * wild, so read routine must be able to handle it > + */ > > maybe this should have a WARN_ON since it should never occur? Fair point. > > + *remainder_size = n % sizeof(struct io_thread_req *); > + memmove( > + remainder, > + ((char *) request_buffer) + > + n/sizeof(struct io_thread_req *), > + *remainder_size > > I am pretty sure the 2nd parameter is off. I think it should be: > ((char *) request_buffer) +(n/sizeof(struct io_thread_req *))*sizeof(struct io_thread_req *) > also copying it off to a shared static buffer? Well spotted. > > + ); > + n = n - *remainder_size; > + } > + } else { > + n = res; > + } > + return n; > +} > + > /* Called without dev->lock held, and only in interrupt context. */ > static void ubd_handler(void) > { > - struct io_thread_req *req; > struct ubd *ubd; > struct list_head *list, *next_ele; > unsigned long flags; > int n; > + int count; > > while(1){ > - n = os_read_file(thread_fd, &req, > - sizeof(struct io_thread_req *)); > - if(n != sizeof(req)){ > > if it is being rewritten n could just be the number of complete buffers for the for loop below That will make it more readable. Agree. > > + n = bulk_req_safe_read( > + thread_fd, > + irq_req_buffer, > + &irq_remainder, > + &irq_remainder_size, > + UBD_REQ_BUFFER_SIZE > + ); > + if (n < 0) { > if(n == -EAGAIN) > break; > printk(KERN_ERR "spurious interrupt in ubd_handler, " > "err = %d\n", -n); > return; > } > - > - blk_end_request(req->req, 0, req->length); > - kfree(req); > + for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { > + blk_end_request( > + (*irq_req_buffer)[count]->req, > + 0, > + (*irq_req_buffer)[count]->length > + ); > + kfree((*irq_req_buffer)[count]); > + } > } > reactivate_fd(thread_fd, UBD_IRQ); > > @@ -1064,6 +1137,28 @@ static int __init ubd_init(void) > if (register_blkdev(fake_major, "ubd")) > return -1; > } > + > + irq_req_buffer = kmalloc( > + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, > + GFP_KERNEL > + ); > + irq_remainder = 0; > + > + if (irq_req_buffer == NULL) { > + printk(KERN_ERR "Failed to initialize ubd buffering\n"); > + return -1; > + } > > Ok, I am really not tracking this, the same buffer allocated twice? One for the irq handler called irq_req_buffer - above. One for the io thread called io_req_buffer - below. Both reuse the same function 100% - this is why it is written this way using two params for "remainder/offset" instead of a single offset. If I use just the offset I cannot reuse the code 100% in both sides of the io (the irq and the io thread). > > + io_req_buffer = kmalloc( > + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, > + GFP_KERNEL > + ); > + > + io_remainder = 0; > + > + if (io_req_buffer == NULL) { > + printk(KERN_ERR "Failed to initialize ubd buffering\n"); > + return -1; > + } > platform_driver_register(&ubd_driver); > mutex_lock(&ubd_lock); > for (i = 0; i < MAX_DEV; i++){ > > > > Sorry of the poor email I am using a web interface and it keeps dropping chars... No worries. A. > > Jim |
From: James M. <jam...@ho...> - 2016-11-09 16:08:15
|
Hi I am not clear on the remainder/remainder_size would not a single offset parameter work? rather than copying it off and back? also max_recs does not seem to used except to calculate max buffer size so would not using a buffer size be easier? something like bulk_req_read( int fd, struct io_thread_req *buf, size_t len, size_t *offset) +static int bulk_req_safe_read( + int fd, + struct io_thread_req * (*request_buffer)[], + struct io_thread_req **remainder, + int *remainder_size, + int max_recs + ) +{ + int n = 0; + int res = 0; + + if (*remainder_size > 0) { + memmove( + (char *) request_buffer, + (char *) remainder, *remainder_size + ); + n = *remainder_size; + } + + res = os_read_file( + fd, + ((char *) request_buffer) + *remainder_size, + sizeof(struct io_thread_req *)*max_recs + - *remainder_size then here it would be res = os_read_file(fd, buf+*offset,len-*offset) Note that if this is ever multithreaded buf and offset or request_buffer/remainder/remainder_size need to be kept separate + ); + if (res > 0) { + n += res; + if ((n % sizeof(struct io_thread_req *)) > 0) { + /* + * Read somehow returned not a multiple of dword + * theoretically possible, but never observed in the + * wild, so read routine must be able to handle it + */ maybe this should have a WARN_ON since it should never occur? + *remainder_size = n % sizeof(struct io_thread_req *); + memmove( + remainder, + ((char *) request_buffer) + + n/sizeof(struct io_thread_req *), + *remainder_size I am pretty sure the 2nd parameter is off. I think it should be: ((char *) request_buffer) +(n/sizeof(struct io_thread_req *))*sizeof(struct io_thread_req *) also copying it off to a shared static buffer? + ); + n = n - *remainder_size; + } + } else { + n = res; + } + return n; +} + /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { - struct io_thread_req *req; struct ubd *ubd; struct list_head *list, *next_ele; unsigned long flags; int n; + int count; while(1){ - n = os_read_file(thread_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(req)){ if it is being rewritten n could just be the number of complete buffers for the for loop below + n = bulk_req_safe_read( + thread_fd, + irq_req_buffer, + &irq_remainder, + &irq_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if (n < 0) { if(n == -EAGAIN) break; printk(KERN_ERR "spurious interrupt in ubd_handler, " "err = %d\n", -n); return; } - - blk_end_request(req->req, 0, req->length); - kfree(req); + for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { + blk_end_request( + (*irq_req_buffer)[count]->req, + 0, + (*irq_req_buffer)[count]->length + ); + kfree((*irq_req_buffer)[count]); + } } reactivate_fd(thread_fd, UBD_IRQ); @@ -1064,6 +1137,28 @@ static int __init ubd_init(void) if (register_blkdev(fake_major, "ubd")) return -1; } + + irq_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + irq_remainder = 0; + + if (irq_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } Ok, I am really not tracking this, the same buffer allocated twice? + io_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + + io_remainder = 0; + + if (io_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } platform_driver_register(&ubd_driver); mutex_lock(&ubd_lock); for (i = 0; i < MAX_DEV; i++){ Sorry of the poor email I am using a web interface and it keeps dropping chars... Jim |
From: <ant...@ko...> - 2016-11-09 08:37:16
|
From: Anton Ivanov <ai...@br...> UBD at present is extremely slow because it handles only one request at a time in the IO thread and IRQ handler. The single request at a time is replaced by handling multiple requests as well as necessary workarounds for short reads/writes. Resulting performance improvement in disk IO - 30% Signed-off-by: Anton Ivanov <ai...@br...> --- arch/um/drivers/ubd.h | 5 ++ arch/um/drivers/ubd_kern.c | 167 ++++++++++++++++++++++++++++++++++++++------- arch/um/drivers/ubd_user.c | 21 +++++- 3 files changed, 166 insertions(+), 27 deletions(-) diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h index 3b48cd2..cc1cc85 100644 --- a/arch/um/drivers/ubd.h +++ b/arch/um/drivers/ubd.h @@ -11,5 +11,10 @@ extern int start_io_thread(unsigned long sp, int *fds_out); extern int io_thread(void *arg); extern int kernel_fd; +extern int ubd_read_poll(int timeout); +extern int ubd_write_poll(int timeout); + +#define UBD_REQ_BUFFER_SIZE 64 + #endif diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f354027..7007ee3 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015-2016 Anton Ivanov (ai...@br...) * Copyright (C) 2000 Jeff Dike (jd...@ka...) * Licensed under the GPL */ @@ -58,6 +59,17 @@ struct io_thread_req { int error; }; + +static struct io_thread_req * (*irq_req_buffer)[]; +static struct io_thread_req *irq_remainder; +static int irq_remainder_size; + +static struct io_thread_req * (*io_req_buffer)[]; +static struct io_thread_req *io_remainder; +static int io_remainder_size; + + + static inline int ubd_test_bit(__u64 bit, unsigned char *data) { __u64 n; @@ -442,29 +454,90 @@ static void do_ubd_request(struct request_queue * q); static int thread_fd = -1; static LIST_HEAD(restart); -/* XXX - move this inside ubd_intr. */ +/* Function to read several request pointers at a time +* handling fractional reads if (and as) needed +*/ + +static int bulk_req_safe_read( + int fd, + struct io_thread_req * (*request_buffer)[], + struct io_thread_req **remainder, + int *remainder_size, + int max_recs + ) +{ + int n = 0; + int res = 0; + + if (*remainder_size > 0) { + memmove( + (char *) request_buffer, + (char *) remainder, *remainder_size + ); + n = *remainder_size; + } + + res = os_read_file( + fd, + ((char *) request_buffer) + *remainder_size, + sizeof(struct io_thread_req *)*max_recs + - *remainder_size + ); + if (res > 0) { + n += res; + if ((n % sizeof(struct io_thread_req *)) > 0) { + /* + * Read somehow returned not a multiple of dword + * theoretically possible, but never observed in the + * wild, so read routine must be able to handle it + */ + *remainder_size = n % sizeof(struct io_thread_req *); + memmove( + remainder, + ((char *) request_buffer) + + n/sizeof(struct io_thread_req *), + *remainder_size + ); + n = n - *remainder_size; + } + } else { + n = res; + } + return n; +} + /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { - struct io_thread_req *req; struct ubd *ubd; struct list_head *list, *next_ele; unsigned long flags; int n; + int count; while(1){ - n = os_read_file(thread_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(req)){ + n = bulk_req_safe_read( + thread_fd, + irq_req_buffer, + &irq_remainder, + &irq_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if (n < 0) { if(n == -EAGAIN) break; printk(KERN_ERR "spurious interrupt in ubd_handler, " "err = %d\n", -n); return; } - - blk_end_request(req->req, 0, req->length); - kfree(req); + for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { + blk_end_request( + (*irq_req_buffer)[count]->req, + 0, + (*irq_req_buffer)[count]->length + ); + kfree((*irq_req_buffer)[count]); + } } reactivate_fd(thread_fd, UBD_IRQ); @@ -1064,6 +1137,28 @@ static int __init ubd_init(void) if (register_blkdev(fake_major, "ubd")) return -1; } + + irq_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + irq_remainder = 0; + + if (irq_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } + io_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + + io_remainder = 0; + + if (io_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } platform_driver_register(&ubd_driver); mutex_lock(&ubd_lock); for (i = 0; i < MAX_DEV; i++){ @@ -1458,31 +1553,51 @@ static int io_count = 0; int io_thread(void *arg) { - struct io_thread_req *req; - int n; + int n, count, written, res; os_fix_helper_signals(); while(1){ - n = os_read_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)){ - if(n < 0) + n = bulk_req_safe_read( + kernel_fd, + io_req_buffer, + &io_remainder, + &io_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if (n < 0) { + if (n == -EAGAIN) { + ubd_read_poll(-1); + continue; + } else { printk("io_thread - read failed, fd = %d, " - "err = %d\n", kernel_fd, -n); - else { - printk("io_thread - short read, fd = %d, " - "length = %d\n", kernel_fd, n); + "err = %d," + "reminder = %d\n", + kernel_fd, -n, io_remainder_size); } - continue; } - io_count++; - do_io(req); - n = os_write_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)) - printk("io_thread - write failed, fd = %d, err = %d\n", - kernel_fd, -n); + + for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { + io_count++; + do_io((*io_req_buffer)[count]); + } + + written = 0; + + do { + res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n); + if (res > 0) { + written += res; + } else { + if (res != -EAGAIN) { + printk("io_thread - read failed, fd = %d, " + "err = %d\n", kernel_fd, -n); + } + } + if (written < n) { + ubd_write_poll(-1); + } + } while (written < n); } return 0; diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index e376f9b..6f74479 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -1,4 +1,5 @@ -/* +/* + * Copyright (C) 2016 Anton Ivanov (ai...@br...) * Copyright (C) 2000, 2001, 2002 Jeff Dike (jd...@ka...) * Copyright (C) 2001 Ridgerun,Inc (gl...@ri...) * Licensed under the GPL @@ -20,6 +21,9 @@ #include "ubd.h" #include <os.h> +#include <poll.h> + +struct pollfd kernel_pollfd; int start_io_thread(unsigned long sp, int *fd_out) { @@ -32,9 +36,12 @@ int start_io_thread(unsigned long sp, int *fd_out) } kernel_fd = fds[0]; + kernel_pollfd.fd = kernel_fd; + kernel_pollfd.events = POLLIN; *fd_out = fds[1]; err = os_set_fd_block(*fd_out, 0); + err = os_set_fd_block(kernel_fd, 0); if (err) { printk("start_io_thread - failed to set nonblocking I/O.\n"); goto out_close; @@ -57,3 +64,15 @@ int start_io_thread(unsigned long sp, int *fd_out) out: return err; } + +int ubd_read_poll(int timeout) +{ + kernel_pollfd.events = POLLIN; + return poll(&kernel_pollfd, 1, timeout); +} +int ubd_write_poll(int timeout) +{ + kernel_pollfd.events = POLLOUT; + return poll(&kernel_pollfd, 1, timeout); +} + -- 2.1.4 |
From: Anton I. <ant...@ko...> - 2016-11-08 09:03:15
|
I will sort out the whitespace and resubmit tonight. Tomorrow morning latest. Apologies (I thought I had the environment set-up so it does not produce whitespace issues). Brgds, A. On 07/11/16 22:30, Richard Weinberger wrote: > Anton, > > On 30.09.2016 08:53, ant...@ko... wrote: >> From: Anton Ivanov <ai...@ko...> >> >> UBD at present is extremely slow because it handles only >> one request at a time in the IO thread and IRQ handler. >> >> The single request at a time is replaced by handling multiple >> requests as well as necessary workarounds for short reads/writes. >> >> Resulting performance improvement in disk IO - 30% >> >> Signed-off-by: Anton Ivanov <ai...@ko...> > In general I think we can merge this in 4.10. > But please run checkpatch.pl and fix all the whitespace issues. :-) > > Daniel, can you apply your blk-mq work on top of this patch? > > Thanks, > //richard > |
From: Richard W. <ri...@no...> - 2016-11-07 22:30:37
|
Anton, On 30.09.2016 08:53, ant...@ko... wrote: > From: Anton Ivanov <ai...@ko...> > > UBD at present is extremely slow because it handles only > one request at a time in the IO thread and IRQ handler. > > The single request at a time is replaced by handling multiple > requests as well as necessary workarounds for short reads/writes. > > Resulting performance improvement in disk IO - 30% > > Signed-off-by: Anton Ivanov <ai...@ko...> In general I think we can merge this in 4.10. But please run checkpatch.pl and fix all the whitespace issues. :-) Daniel, can you apply your blk-mq work on top of this patch? Thanks, //richard |
From: Richard W. <ri...@no...> - 2016-10-11 16:00:58
|
Hi guys, I'm very sorry but due to travelling and a flu I simply had no time to prepare a pull request and review patches. Thanks, //richard |
From: <ant...@ko...> - 2016-09-30 06:53:52
|
From: Anton Ivanov <ai...@ko...> UBD at present is extremely slow because it handles only one request at a time in the IO thread and IRQ handler. The single request at a time is replaced by handling multiple requests as well as necessary workarounds for short reads/writes. Resulting performance improvement in disk IO - 30% Signed-off-by: Anton Ivanov <ai...@ko...> --- arch/um/drivers/ubd.h | 5 ++ arch/um/drivers/ubd_kern.c | 161 ++++++++++++++++++++++++++++++++++++++------- arch/um/drivers/ubd_user.c | 19 +++++- 3 files changed, 159 insertions(+), 26 deletions(-) diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h index 3b48cd2..cc1cc85 100644 --- a/arch/um/drivers/ubd.h +++ b/arch/um/drivers/ubd.h @@ -11,5 +11,10 @@ extern int start_io_thread(unsigned long sp, int *fds_out); extern int io_thread(void *arg); extern int kernel_fd; +extern int ubd_read_poll(int timeout); +extern int ubd_write_poll(int timeout); + +#define UBD_REQ_BUFFER_SIZE 64 + #endif diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f354027..3f610df 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015-2016 Anton Ivanov (ai...@br...) * Copyright (C) 2000 Jeff Dike (jd...@ka...) * Licensed under the GPL */ @@ -58,6 +59,17 @@ struct io_thread_req { int error; }; + +static struct io_thread_req* (*irq_req_buffer) []; +static struct io_thread_req * irq_remainder; +static int irq_remainder_size; + +static struct io_thread_req* (*io_req_buffer) []; +static struct io_thread_req * io_remainder; +static int io_remainder_size; + + + static inline int ubd_test_bit(__u64 bit, unsigned char *data) { __u64 n; @@ -442,29 +454,88 @@ static void do_ubd_request(struct request_queue * q); static int thread_fd = -1; static LIST_HEAD(restart); -/* XXX - move this inside ubd_intr. */ +/* Function to read several request pointers at a time +* handling fractional reads if (and as) needed +*/ + +static int bulk_req_safe_read( + int fd, + struct io_thread_req * (*request_buffer) [], + struct io_thread_req ** remainder, + int * remainder_size, + int max_recs + ) +{ + int n = 0; + int res = 0; + + if (*remainder_size > 0) { + memmove( + (char *) request_buffer, + (char *) remainder, * remainder_size + ); + n = * remainder_size; + } + + res = os_read_file( + fd, + ((char *) request_buffer) + * remainder_size, + sizeof(struct io_thread_req *) * max_recs - *remainder_size + ); + if (res > 0) { + n += res; + if ((n % sizeof(struct io_thread_req *)) > 0) { + /* + * Read somehow returned not a multiple of dword + * theoretically possible, but never observed in the + * wild, so read routine must be able to handle it + */ + *remainder_size = n % sizeof(struct io_thread_req *); + memmove( + remainder, + ((char *) request_buffer) + n/sizeof(struct io_thread_req *), + *remainder_size + ); + n = n - *remainder_size; + } + } else { + n = res; + } + return n; +} + /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { - struct io_thread_req *req; struct ubd *ubd; struct list_head *list, *next_ele; unsigned long flags; int n; + int count; while(1){ - n = os_read_file(thread_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(req)){ + n = bulk_req_safe_read( + thread_fd, + irq_req_buffer, + &irq_remainder, + &irq_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if(n < 0){ if(n == -EAGAIN) break; printk(KERN_ERR "spurious interrupt in ubd_handler, " "err = %d\n", -n); return; } - - blk_end_request(req->req, 0, req->length); - kfree(req); + for (count=0;count < n /sizeof(struct io_thread_req *);count++) { + blk_end_request( + (* irq_req_buffer)[count]->req, + 0, + (* irq_req_buffer)[count]->length + ); + kfree((* irq_req_buffer)[count]); + } } reactivate_fd(thread_fd, UBD_IRQ); @@ -1064,6 +1135,28 @@ static int __init ubd_init(void) if (register_blkdev(fake_major, "ubd")) return -1; } + + irq_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + irq_remainder = 0; + + if(irq_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } + io_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + + io_remainder = 0; + + if(io_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } platform_driver_register(&ubd_driver); mutex_lock(&ubd_lock); for (i = 0; i < MAX_DEV; i++){ @@ -1458,31 +1551,49 @@ static int io_count = 0; int io_thread(void *arg) { - struct io_thread_req *req; - int n; + int n, count, written, res; os_fix_helper_signals(); while(1){ - n = os_read_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)){ - if(n < 0) + n = bulk_req_safe_read( + kernel_fd, + io_req_buffer, + &io_remainder, + &io_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if(n < 0){ + if(n == -EAGAIN) { + ubd_read_poll(-1); + continue; + } else { printk("io_thread - read failed, fd = %d, " "err = %d\n", kernel_fd, -n); - else { - printk("io_thread - short read, fd = %d, " - "length = %d\n", kernel_fd, n); } - continue; + } + + for (count=0;count < n /sizeof(struct io_thread_req *);count++) { + io_count++; + do_io((* io_req_buffer)[count]); } - io_count++; - do_io(req); - n = os_write_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)) - printk("io_thread - write failed, fd = %d, err = %d\n", - kernel_fd, -n); + + written = 0; + + do { + res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n); + if (res > 0) { + written += res; + } else { + if (res != -EAGAIN) { + printk("io_thread - read failed, fd = %d, " + "err = %d\n", kernel_fd, -n); + } + } + if (written < n) { + ubd_write_poll(-1); + } + } while (written < n); } return 0; diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index e376f9b..d3240b5 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -1,4 +1,5 @@ -/* +/* + * Copyright (C) 2016 Anton Ivanov (ai...@br...) * Copyright (C) 2000, 2001, 2002 Jeff Dike (jd...@ka...) * Copyright (C) 2001 Ridgerun,Inc (gl...@ri...) * Licensed under the GPL @@ -20,6 +21,9 @@ #include "ubd.h" #include <os.h> +#include <poll.h> + +struct pollfd kernel_pollfd; int start_io_thread(unsigned long sp, int *fd_out) { @@ -32,9 +36,12 @@ int start_io_thread(unsigned long sp, int *fd_out) } kernel_fd = fds[0]; + kernel_pollfd.fd = kernel_fd; + kernel_pollfd.events = POLLIN; *fd_out = fds[1]; err = os_set_fd_block(*fd_out, 0); + err = os_set_fd_block(kernel_fd, 0); if (err) { printk("start_io_thread - failed to set nonblocking I/O.\n"); goto out_close; @@ -57,3 +64,13 @@ int start_io_thread(unsigned long sp, int *fd_out) out: return err; } + +int ubd_read_poll(int timeout) { + kernel_pollfd.events = POLLIN; + return poll(&kernel_pollfd, 1, timeout); +} +int ubd_write_poll(int timeout) { + kernel_pollfd.events = POLLOUT; + return poll(&kernel_pollfd, 1, timeout); +} + -- 2.1.4 |
From: Anton I. <ant...@ko...> - 2016-09-30 06:53:20
|
I noticed a formatting error and a logical error in the short read "safety net". It is never invoked, but none the less should be fixed. A revised patch with fixed formatting and a fix for the logical error will follow shortly. Performance figures are unchanged: 30% gain to start off with on raw read, 17% on find /usr -exec cat {} A. On 29/09/16 21:36, ant...@ko... wrote: > From: Anton Ivanov <ai...@br...> > > UBD at present is extremely slow because it handles only > one request at a time in the IO thread and IRQ handler. > > The single request at a time is replaced by handling multiple > requests as well as necessary workarounds for short reads/writes. > > Resulting performance improvement in disk IO - 30% > > Signed-off-by: Anton Ivanov <ai...@br...> > --- > arch/um/drivers/ubd.h | 5 ++ > arch/um/drivers/ubd_kern.c | 161 ++++++++++++++++++++++++++++++++++++++------- > arch/um/drivers/ubd_user.c | 19 +++++- > 3 files changed, 159 insertions(+), 26 deletions(-) > > diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h > index 3b48cd2..cc1cc85 100644 > --- a/arch/um/drivers/ubd.h > +++ b/arch/um/drivers/ubd.h > @@ -11,5 +11,10 @@ extern int start_io_thread(unsigned long sp, int *fds_out); > extern int io_thread(void *arg); > extern int kernel_fd; > > +extern int ubd_read_poll(int timeout); > +extern int ubd_write_poll(int timeout); > + > +#define UBD_REQ_BUFFER_SIZE 64 > + > #endif > > diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c > index f354027..91f3354 100644 > --- a/arch/um/drivers/ubd_kern.c > +++ b/arch/um/drivers/ubd_kern.c > @@ -1,4 +1,5 @@ > /* > + * Copyright (C) 2015-2016 Anton Ivanov (ai...@br...) > * Copyright (C) 2000 Jeff Dike (jd...@ka...) > * Licensed under the GPL > */ > @@ -58,6 +59,17 @@ struct io_thread_req { > int error; > }; > > + > +static struct io_thread_req* (*irq_req_buffer) []; > +static struct io_thread_req * irq_remainder; > +static int irq_remainder_size; > + > +static struct io_thread_req* (*io_req_buffer) []; > +static struct io_thread_req * io_remainder; > +static int io_remainder_size; > + > + > + > static inline int ubd_test_bit(__u64 bit, unsigned char *data) > { > __u64 n; > @@ -442,29 +454,88 @@ static void do_ubd_request(struct request_queue * q); > static int thread_fd = -1; > static LIST_HEAD(restart); > > -/* XXX - move this inside ubd_intr. */ > +/* Function to read several request pointers at a time > +* handling fractional reads if (and as) needed > +*/ > + > +static int bulk_req_safe_read( > + int fd, > + struct io_thread_req* (*request_buffer) [], > + struct io_thread_req * remainder, This should be ** and the code modified accordingly - you need the pointer to the "short read" buffer, not where the short read buffer is pointing to as that is not relevant for what it tries to do. > + int * remainder_size, > + int max_recs > + ) > +{ > + int n = 0; > + int res = 0; > + > + if (*remainder_size > 0) { > + memmove( > + (char *) request_buffer, > + (char *) & remainder, * remainder_size > + ); > + n = * remainder_size; > + } > + > + res = os_read_file( > + fd, > + ((char *) request_buffer) + * remainder_size, > + sizeof(struct io_thread_req *) * max_recs - *remainder_size > + ); > + if (res > 0) { > + n += res; > + if ((n % sizeof(struct io_thread_req *)) > 0) { > + /* > + * Read somehow returned not a multiple of dword > + * theoretically possible, but never observed in the > + * wild, so read routine must be able to handle it > + */ > + *remainder_size = n % sizeof(struct io_thread_req *); > + memmove( > + & remainder, > + ((char *) request_buffer) + n/sizeof(struct io_thread_req *), > + *remainder_size > + ); > + n = n - *remainder_size; > + } > + } else { > + n = res; > + } > + return n; > +} > + > /* Called without dev->lock held, and only in interrupt context. */ > static void ubd_handler(void) > { > - struct io_thread_req *req; > struct ubd *ubd; > struct list_head *list, *next_ele; > unsigned long flags; > int n; > + int count; > > while(1){ > - n = os_read_file(thread_fd, &req, > - sizeof(struct io_thread_req *)); > - if(n != sizeof(req)){ > + n = bulk_req_safe_read( > + thread_fd, > + irq_req_buffer, > + irq_remainder, > + &irq_remainder_size, > + UBD_REQ_BUFFER_SIZE > + ); > + if(n < 0){ > if(n == -EAGAIN) > break; > printk(KERN_ERR "spurious interrupt in ubd_handler, " > "err = %d\n", -n); > return; > } > - > - blk_end_request(req->req, 0, req->length); > - kfree(req); > + for (count=0;count < n /sizeof(struct io_thread_req *);count++) { > + blk_end_request( > + (* irq_req_buffer)[count]->req, > + 0, > + (* irq_req_buffer)[count]->length > + ); > + kfree((* irq_req_buffer)[count]); > + } > } > reactivate_fd(thread_fd, UBD_IRQ); > > @@ -1064,6 +1135,28 @@ static int __init ubd_init(void) > if (register_blkdev(fake_major, "ubd")) > return -1; > } > + > + irq_req_buffer = kmalloc( > + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, > + GFP_KERNEL > + ); > + irq_remainder = 0; > + > + if(irq_req_buffer == NULL) { > + printk(KERN_ERR "Failed to initialize ubd buffering\n"); > + return -1; > + } > + io_req_buffer = kmalloc( > + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, > + GFP_KERNEL > + ); > + > + io_remainder = 0; > + > + if(io_req_buffer == NULL) { > + printk(KERN_ERR "Failed to initialize ubd buffering\n"); > + return -1; > + } > platform_driver_register(&ubd_driver); > mutex_lock(&ubd_lock); > for (i = 0; i < MAX_DEV; i++){ > @@ -1458,31 +1551,49 @@ static int io_count = 0; > > int io_thread(void *arg) > { > - struct io_thread_req *req; > - int n; > + int n, count, written, res; > > os_fix_helper_signals(); > > while(1){ > - n = os_read_file(kernel_fd, &req, > - sizeof(struct io_thread_req *)); > - if(n != sizeof(struct io_thread_req *)){ > - if(n < 0) > + n = bulk_req_safe_read( > + kernel_fd, > + io_req_buffer, > + io_remainder, > + &io_remainder_size, > + UBD_REQ_BUFFER_SIZE > + ); > + if(n < 0){ > + if(n == -EAGAIN) { > + ubd_read_poll(-1); > + continue; > + } else { > printk("io_thread - read failed, fd = %d, " > "err = %d\n", kernel_fd, -n); > - else { > - printk("io_thread - short read, fd = %d, " > - "length = %d\n", kernel_fd, n); > } > - continue; > + } > + > + for (count=0;count < n /sizeof(struct io_thread_req *);count++) { > + io_count++; > + do_io((* io_req_buffer)[count]); > } > - io_count++; > - do_io(req); > - n = os_write_file(kernel_fd, &req, > - sizeof(struct io_thread_req *)); > - if(n != sizeof(struct io_thread_req *)) > - printk("io_thread - write failed, fd = %d, err = %d\n", > - kernel_fd, -n); > + > + written = 0; > + > + do { > + res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n); > + if (res > 0) { > + written += res; > + } else { > + if (res != -EAGAIN) { > + printk("io_thread - read failed, fd = %d, " > + "err = %d\n", kernel_fd, -n); > + } > + } > + if (written < n) { > + ubd_write_poll(-1); > + } > + } while (written < n); > } > > return 0; > diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c > index e376f9b..2a7d5b6 100644 > --- a/arch/um/drivers/ubd_user.c > +++ b/arch/um/drivers/ubd_user.c > @@ -1,4 +1,5 @@ > -/* > +/* > + * Copyright (C) 2016 Anton Ivanov (ai...@br...) > * Copyright (C) 2000, 2001, 2002 Jeff Dike (jd...@ka...) > * Copyright (C) 2001 Ridgerun,Inc (gl...@ri...) > * Licensed under the GPL > @@ -20,6 +21,9 @@ > > #include "ubd.h" > #include <os.h> > +#include <poll.h> > + > +struct pollfd kernel_pollfd; > > int start_io_thread(unsigned long sp, int *fd_out) > { > @@ -32,9 +36,12 @@ int start_io_thread(unsigned long sp, int *fd_out) > } > > kernel_fd = fds[0]; > + kernel_pollfd.fd = kernel_fd; > + kernel_pollfd.events = POLLIN; > *fd_out = fds[1]; > > err = os_set_fd_block(*fd_out, 0); > + err = os_set_fd_block(kernel_fd, 0); > if (err) { > printk("start_io_thread - failed to set nonblocking I/O.\n"); > goto out_close; > @@ -57,3 +64,13 @@ int start_io_thread(unsigned long sp, int *fd_out) > out: > return err; > } > + > +int ubd_read_poll(int timeout) { > + kernel_pollfd.events = POLLIN; > + return poll(&kernel_pollfd, 1, timeout); > +} > +int ubd_write_poll(int timeout) { > + kernel_pollfd.events = POLLOUT; > + return poll(&kernel_pollfd, 1, timeout); > +} > + |
From: <ant...@ko...> - 2016-09-29 20:37:23
|
From: Anton Ivanov <ai...@br...> UBD at present is extremely slow because it handles only one request at a time in the IO thread and IRQ handler. The single request at a time is replaced by handling multiple requests as well as necessary workarounds for short reads/writes. Resulting performance improvement in disk IO - 30% Signed-off-by: Anton Ivanov <ai...@br...> --- arch/um/drivers/ubd.h | 5 ++ arch/um/drivers/ubd_kern.c | 161 ++++++++++++++++++++++++++++++++++++++------- arch/um/drivers/ubd_user.c | 19 +++++- 3 files changed, 159 insertions(+), 26 deletions(-) diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h index 3b48cd2..cc1cc85 100644 --- a/arch/um/drivers/ubd.h +++ b/arch/um/drivers/ubd.h @@ -11,5 +11,10 @@ extern int start_io_thread(unsigned long sp, int *fds_out); extern int io_thread(void *arg); extern int kernel_fd; +extern int ubd_read_poll(int timeout); +extern int ubd_write_poll(int timeout); + +#define UBD_REQ_BUFFER_SIZE 64 + #endif diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f354027..91f3354 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015-2016 Anton Ivanov (ai...@br...) * Copyright (C) 2000 Jeff Dike (jd...@ka...) * Licensed under the GPL */ @@ -58,6 +59,17 @@ struct io_thread_req { int error; }; + +static struct io_thread_req* (*irq_req_buffer) []; +static struct io_thread_req * irq_remainder; +static int irq_remainder_size; + +static struct io_thread_req* (*io_req_buffer) []; +static struct io_thread_req * io_remainder; +static int io_remainder_size; + + + static inline int ubd_test_bit(__u64 bit, unsigned char *data) { __u64 n; @@ -442,29 +454,88 @@ static void do_ubd_request(struct request_queue * q); static int thread_fd = -1; static LIST_HEAD(restart); -/* XXX - move this inside ubd_intr. */ +/* Function to read several request pointers at a time +* handling fractional reads if (and as) needed +*/ + +static int bulk_req_safe_read( + int fd, + struct io_thread_req* (*request_buffer) [], + struct io_thread_req * remainder, + int * remainder_size, + int max_recs + ) +{ + int n = 0; + int res = 0; + + if (*remainder_size > 0) { + memmove( + (char *) request_buffer, + (char *) & remainder, * remainder_size + ); + n = * remainder_size; + } + + res = os_read_file( + fd, + ((char *) request_buffer) + * remainder_size, + sizeof(struct io_thread_req *) * max_recs - *remainder_size + ); + if (res > 0) { + n += res; + if ((n % sizeof(struct io_thread_req *)) > 0) { + /* + * Read somehow returned not a multiple of dword + * theoretically possible, but never observed in the + * wild, so read routine must be able to handle it + */ + *remainder_size = n % sizeof(struct io_thread_req *); + memmove( + & remainder, + ((char *) request_buffer) + n/sizeof(struct io_thread_req *), + *remainder_size + ); + n = n - *remainder_size; + } + } else { + n = res; + } + return n; +} + /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { - struct io_thread_req *req; struct ubd *ubd; struct list_head *list, *next_ele; unsigned long flags; int n; + int count; while(1){ - n = os_read_file(thread_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(req)){ + n = bulk_req_safe_read( + thread_fd, + irq_req_buffer, + irq_remainder, + &irq_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if(n < 0){ if(n == -EAGAIN) break; printk(KERN_ERR "spurious interrupt in ubd_handler, " "err = %d\n", -n); return; } - - blk_end_request(req->req, 0, req->length); - kfree(req); + for (count=0;count < n /sizeof(struct io_thread_req *);count++) { + blk_end_request( + (* irq_req_buffer)[count]->req, + 0, + (* irq_req_buffer)[count]->length + ); + kfree((* irq_req_buffer)[count]); + } } reactivate_fd(thread_fd, UBD_IRQ); @@ -1064,6 +1135,28 @@ static int __init ubd_init(void) if (register_blkdev(fake_major, "ubd")) return -1; } + + irq_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + irq_remainder = 0; + + if(irq_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } + io_req_buffer = kmalloc( + sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, + GFP_KERNEL + ); + + io_remainder = 0; + + if(io_req_buffer == NULL) { + printk(KERN_ERR "Failed to initialize ubd buffering\n"); + return -1; + } platform_driver_register(&ubd_driver); mutex_lock(&ubd_lock); for (i = 0; i < MAX_DEV; i++){ @@ -1458,31 +1551,49 @@ static int io_count = 0; int io_thread(void *arg) { - struct io_thread_req *req; - int n; + int n, count, written, res; os_fix_helper_signals(); while(1){ - n = os_read_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)){ - if(n < 0) + n = bulk_req_safe_read( + kernel_fd, + io_req_buffer, + io_remainder, + &io_remainder_size, + UBD_REQ_BUFFER_SIZE + ); + if(n < 0){ + if(n == -EAGAIN) { + ubd_read_poll(-1); + continue; + } else { printk("io_thread - read failed, fd = %d, " "err = %d\n", kernel_fd, -n); - else { - printk("io_thread - short read, fd = %d, " - "length = %d\n", kernel_fd, n); } - continue; + } + + for (count=0;count < n /sizeof(struct io_thread_req *);count++) { + io_count++; + do_io((* io_req_buffer)[count]); } - io_count++; - do_io(req); - n = os_write_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)) - printk("io_thread - write failed, fd = %d, err = %d\n", - kernel_fd, -n); + + written = 0; + + do { + res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n); + if (res > 0) { + written += res; + } else { + if (res != -EAGAIN) { + printk("io_thread - read failed, fd = %d, " + "err = %d\n", kernel_fd, -n); + } + } + if (written < n) { + ubd_write_poll(-1); + } + } while (written < n); } return 0; diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index e376f9b..2a7d5b6 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -1,4 +1,5 @@ -/* +/* + * Copyright (C) 2016 Anton Ivanov (ai...@br...) * Copyright (C) 2000, 2001, 2002 Jeff Dike (jd...@ka...) * Copyright (C) 2001 Ridgerun,Inc (gl...@ri...) * Licensed under the GPL @@ -20,6 +21,9 @@ #include "ubd.h" #include <os.h> +#include <poll.h> + +struct pollfd kernel_pollfd; int start_io_thread(unsigned long sp, int *fd_out) { @@ -32,9 +36,12 @@ int start_io_thread(unsigned long sp, int *fd_out) } kernel_fd = fds[0]; + kernel_pollfd.fd = kernel_fd; + kernel_pollfd.events = POLLIN; *fd_out = fds[1]; err = os_set_fd_block(*fd_out, 0); + err = os_set_fd_block(kernel_fd, 0); if (err) { printk("start_io_thread - failed to set nonblocking I/O.\n"); goto out_close; @@ -57,3 +64,13 @@ int start_io_thread(unsigned long sp, int *fd_out) out: return err; } + +int ubd_read_poll(int timeout) { + kernel_pollfd.events = POLLIN; + return poll(&kernel_pollfd, 1, timeout); +} +int ubd_write_poll(int timeout) { + kernel_pollfd.events = POLLOUT; + return poll(&kernel_pollfd, 1, timeout); +} + -- 2.1.4 |
From: <ant...@ko...> - 2016-09-29 20:37:16
|
Hi Richard, hi list. I had some difficulties evaluating the actual performance difference because of the strange behaviour with the ubd speed reduction over time (as per my earlier "There is something rotten" email). Overall, if I take the only the first few dd runs to read the entire disk and compare like for like (first run without patch vs first run with patch) I get 30% improvement on dd-ing a 16G sparse ubd device. The performance on find /usr -type f -exec cat {} > /dev/null \; increases 17%. The patch is called "Phase 1" for a reason - by bulking the requests we set-up the scene for a later replacement of pread/pwrite with preadv/pwritev in next series of patches which should increase the speed further by at least the same amount (if not more). |
From: Anton I. <ant...@ko...> - 2016-09-24 22:13:01
|
Hi Richard, hi list, I got around to devote some time to my patchsets and while working on my ubd block read one, I observed the following behaviour with stock 4.8.0-rc7 On a freshly booted image, stock 4.8.0-rc7, Debian jessie userspace: root@wyvern-uml:~# while true; do dd if=/dev/ubda of=/dev/null bs=1M ; done 4096+0 records in 4096+0 records out 4294967296 bytes (4.3 GB) copied, 8.14403 s, 527 MB/s 4096+0 records in 4096+0 records out 4294967296 bytes (4.3 GB) copied, 9.52683 s, 451 MB/s 4096+0 records in 4096+0 records out 4294967296 bytes (4.3 GB) copied, 10.1613 s, 423 MB/s 4096+0 records in 4096+0 records out 4294967296 bytes (4.3 GB) copied, 10.2111 s, 421 MB/s This gets progressively worse until it reaches about 380MB/s in 5-10 more runs. The rate at which it slows down decreases overtime. A. |