Closed wjhun closed 5 years ago
I'm able to get a ruby hello world using the munmap branch. This branch isn't quite ready for merging - the implementation is kind of a hack to just get ruby unstuck. Because of some idiosyncrasies with the bitmap allocator, the existing code could be potentially unsafe in certain situations. I have a plan for fixing the bitmap allocator logic (also allowing unaligned allocations - would be good for tfs) to make these unmaps more straightforward. Prob 1-2 add'l days to fix.
A few notes about this ruby/sinatra test:
Possibilities for the short term:
For the longer term:
$ ops load ruby_2.3.1 -p 4567 -c config.json
Extracting /home/wjhun/.ops/packages/ruby_2.3.1.tar.gz to /home/wjhun/.ops/.staging/ruby_2.3.1
[ruby myapp.rb -o 0.0.0.0]
booting /home/wjhun/.ops/images/ruby.img ...
assigned: 10.0.2.15
[2019-03-10 06:48:50] INFO WEBrick 1.3.1
[2019-03-10 06:48:50] INFO ruby 2.3.1 (2016-04-26) [x86_64-linux-gnu]
== Sinatra (v2.0.5) has taken the stage on 4567 for development with backup from WEBrick
[2019-03-10 06:48:50] INFO WEBrick::HTTPServer#start: pid=1 port=4567
10.0.2.2 - - [10/Mar/2019:06:49:20 +0000] "GET / HTTP/1.1" 200 12 14.7117
10.0.2.2 - - [10/Mar/2019:06:49:05 UTC] "GET / HTTP/1.1" 200 12
- -> /
10.0.2.2 - - [10/Mar/2019:07:04:08 +0000] "GET / HTTP/1.1" 200 12 14.0485
10.0.2.2 - - [10/Mar/2019:07:03:54 UTC] "GET / HTTP/1.1" 200 12
- -> /
might be worth breaking these out into separate issues so we can track them
Various issues here have been resolved, including demand paging for anonymous mmaps (#607), mmap and munmap updates (#804, #811). With #830, the ruby/sinatra webserver test above runs:
$ cat myapp.rb
# myapp.rb
require 'sinatra'
get '/' do
'Hello world!'
end
$ ops load ruby_2.3.1 -c config.json -p 4567
warning: overwriting existing file /lib/x86_64-linux-gnu/libnss_dns.so.2 hostpath old: /home/wjhun/.ops/.staging/ruby_2.3.1/sysroot/lib/x86_64-linux-gnu/libnss_dns.so.2 new: lib/x86_64-linux-gnu/libnss_dns.so.2
[ruby myapp.rb -o 0.0.0.0]
booting /home/wjhun/.ops/images/ruby.img ...
assigned: 10.0.2.15
[2019-05-24 18:12:42] INFO WEBrick 1.3.1
[2019-05-24 18:12:42] INFO ruby 2.3.1 (2016-04-26) [x86_64-linux-gnu]
== Sinatra (v2.0.5) has taken the stage on 4567 for development with backup from WEBrick
[2019-05-24 18:12:42] INFO WEBrick::HTTPServer#start: pid=1 port=4567
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.1212
10.0.2.2 - - [24/May/2019:18:12:45 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0051
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0040
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0045
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0039
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0041
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0037
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0042
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0039
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
10.0.2.2 - - [24/May/2019:18:12:46 +0000] "GET / HTTP/1.1" 200 12 0.0043
10.0.2.2 - - [24/May/2019:18:12:46 UTC] "GET / HTTP/1.0" 200 12
- -> /
$ ab -n 10 http://127.0.0.1:4567/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient).....done
Server Software: WEBrick/1.3.1
Server Hostname: 127.0.0.1
Server Port: 4567
Document Path: /
Document Length: 12 bytes
Concurrency Level: 1
Time taken for tests: 0.514 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 2890 bytes
HTML transferred: 120 bytes
Requests per second: 19.45 [#/sec] (mean)
Time per request: 51.412 [ms] (mean)
Time per request: 51.412 [ms] (mean, across all concurrent requests)
Transfer rate: 5.49 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 24 51 71.6 26 254
Waiting: 23 48 71.6 24 251
Total: 24 51 71.6 27 254
Percentage of the requests served within a certain time (ms)
50% 27
66% 27
75% 34
80% 43
90% 254
95% 254
98% 254
99% 254
100% 254 (longest request)
ruby is doing a lot of mmaping of large spaces, only to immediately unmap them entirely or at least partially. Since we don't implement munmap(2) and are doing physical allocations with each mmap (no demand paging), we eventually run out of physical pages to dole out (at least in the sizes requested).
There are a number of issues here to deal with over the longer term, but for today it may suffice to implement munmap and remove such mappings. If we really want to be lazy, we can just unmap the space, return the physical allocation and leave the virtual / rangemap allocation in place rather than try to undo it. (I'm going to start here to see if it's good enough for a ruby demo.)
Of course, we might just run out of virtual address space then. To do the right thing:
Although we'd still need to do #2 for physical id heap deallocations...
We could also discuss doing a sort of poor man's demand paging just for anonymous, private mappings. This is possible now that we have the vmaps structure in place.