background 199x internet-hype; research community focuses on www-services scalaserver lrp (talk about later) server architecture change multi-process pre-allocated proesses event driven (?) + no context switch - complicated programming, need non-blocking system call multi-thread dynamic content CGI (one process per cgi request; one persistent process for a cgi program; reside in main server program) resource charging is still weird problem 1. some resource usage in kernel is not charged 2. resource management unit is diffrent from process/thread might be larger than a process (mult-process application) ...... might be smaller than a process/thread (multi-thread, each thread does distinguishable work) author's lrp work solves problem 1 What is the resource management boundary? ... ... resource management (rc) 1. rc: abstract os entity; all resources; for an application (dynamic binding with threads) 2. containers have attribute: scheduling parameters, resource limit 3. resource accounting entity (kernel AND user) Q: how to do kernel accounting? We might need to change I/O handling in order to do accurate kernel accounting. LRP paper gave an example. 4. kernel uses takes RC-information for better management; user program can also use the RC information. RC details operations on rc 1. create a new one, by default by fork (rc is a file descriptor) 2. set parent 3. release 4. sharing 5. set and read the info. of a container (why do we want user-thread to learn it?) operation on rc and thread 1. binding, unbind, know the binding add kernel accounting LRP, etc. ================================= Usage of RC 1) scheduling multiple threads ==> one resource container (relatively easy) (they all share that container's attribute, or whatever) one thread including many resource containers (on page 7, :S, not that convincing, actually) in priority system, not just use its current container to decide the thread's priority, use its recent container history one thing i agree is that it is too time-consuming to change a thread's priority every time when its binding is changed (the exact implementation is fixed-share always get 10% from parent time-share equally split the remaining resource with its sibling thread is only associated to leaf container; complicated if not; implemented using lottery scheduling. is thre security concern? yes) 2) use for other resource disk bandwidth, physical memory rc is just a mechanism in network socket (help defend DOS): socket is given the RC of the creator process Q: to defend DOS, any type it cannot defend? 3) resource container hierarchy subcontainer, very similar to lottery Q: what is the pros and cons of RC (performance, security, etc.) ========================================================= How to apply RC on servers for multi-thread (one thread per connection) for event-driven (more like the application will read the information and adjust by itself at user-level) for CGI (make CGI process to take the rc) other usage assign RC to sockets limit a set of RC's cpu usage (not just scheduling decision) RC is simply a mechanism, an accounting mechanism system and application and use it for many different usage (scheduling, access control, etc.) ~~~~~~~~~~~~~ performance benchmark: even-driven single process server emp1: priority control 1) benefit from rc (for event-driven server!!) 2) beneift from kernel accounting *emp2: how cgi would affect the throughput of static requests 1) many cgi processes; time-sharing would lead to small web-server cpu sharing 2) lrp even worsened the problem because static spent more time in kernel ============== about their change to `select` the problem with select is that it is linear to the number of ports under monitor they add new syscall: interested, revoke_interests, wait for next event (kernel will provide event one by one based on priority) About LRP ------------ 1. early demultiplexing (original design is to put every incoming packet in a common queue and then do TCP/IP and finally put to socket queue; now change to put to per-socket queue at th every beginning) 2. lazy handling (don't handle until that socket has a `receiver' sys call) accept(): take a request off a specified socket; if there is nothing pending in that socket, the caller could either be blocked or get an error return depending on socket's property (blocking or non-blockg) poll() select() both poll and select allows you to specify a set of file-descriptor; the caller will be blocked; it will be woken up once some data is available on that file descriptor (select also allows you to specify read/write/others) a big project http://www.cs.rice.edu/CS/Systems/ScalaServer/