<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1014297917047073169</id><updated>2011-11-17T06:31:57.870-05:00</updated><category term='uml'/><category term='milestones'/><category term='mmotm'/><category term='modules'/><category term='proposal'/><category term='filesystem'/><category term='project'/><category term='gdb'/><category term='threadgroup'/><category term='lkml'/><category term='presentation'/><category term='locking'/><title type='text'>Linux CGroups: Subsystems as Modules</title><subtitle type='html'>the musings of a curious kernel hacker</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-1130408375784903985</id><published>2011-04-12T22:50:00.005-04:00</published><updated>2011-04-14T15:14:33.160-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='threadgroup'/><category scheme='http://www.blogger.com/atom/ns#' term='mmotm'/><category scheme='http://www.blogger.com/atom/ns#' term='locking'/><title type='text'>double-double-toil-and-trouble-check locking</title><content type='html'>After nearly two years of on-and-off work, my &lt;a href="http://lkml.org/lkml/2011/2/7/418"&gt;cgroups threadgroup interface patches&lt;/a&gt; have attained a sufficiently polished state and been accepted into the &lt;a href="http://lwn.net/Articles/311677/"&gt;mmotm tree&lt;/a&gt;. This is super exciting! It was hard, interesting, enlightening work from beginning to end, and was the most enjoyable experience I've ever had learning about real-world code:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;what kinds of tricks, rules, and infrastructure must go into maintaining a million-line codebase with as many contributors&lt;/li&gt;&lt;li&gt;how to write code that is both complicated and perfect: no symbol may be  out of place in either aesthetic style or correct functionality&lt;/li&gt;&lt;li&gt;how to write code that interacts with more parts of a codebase than  whose details you can possibly understand; how to intuit what parts you  will bump into meaningfully and know exactly where to look for details  that will tell you how to negotiate the right interaction&lt;/li&gt;&lt;li&gt;justifying the usefulness of your code before anybody will even consider pulling from you &lt;/li&gt;&lt;/ol&gt;So, props to the core linux guys: they run a very tight ship, but living conditions are pleasant, and it sails to great places. Having my patches pulled is the ultimate validation that my work was not only interesting and challenging but also new and useful - a full-house of project qualities rarer even than talented programmers. It has been a blast.&lt;br /&gt;&lt;br /&gt;What is the big deal? These patches solved an interesting and complicated problem in an interesting and complicated way. The challenge was to atomically migrate all tasks in a threadgroup (in non-linux speak, "threads in a multithreaded process") from one cgroup to another - no activity may cause a thread in that group to remain outside of the target cgroup at the end of the operation (think interleaving &lt;span style="font-family:courier new;"&gt;fork&lt;/span&gt;/&lt;span style="font-family:courier new;"&gt;exec&lt;/span&gt;/&lt;span style="font-family:courier new;"&gt;exit&lt;/span&gt; dances). Here is the landscape of thread management in linux:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Each &lt;span style="font-family:courier new;"&gt;task_struct&lt;/span&gt; ("thread") is on a list for its group, called &lt;span style="font-family:courier new;"&gt;tsk-&amp;gt;thread_group&lt;/span&gt;, and also has a pointer to the leader thread of the group, called &lt;span style="font-family:courier new;"&gt;tsk-&amp;gt;group_leader&lt;/span&gt; (the leader's leader pointer points to himself).  further, the leaders of all groups are on another system-wide list. The standard way to iterate over these lists is with macros called &lt;a href="http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/include/linux/sched.h#L2219"&gt;&lt;span style="font-family:courier new;"&gt;do_each_thread&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;while_each_thread&lt;/span&gt;&lt;/a&gt;.  All these lists and pointers are protected by RCU and/or the global &lt;span style="font-family:courier new;"&gt;tasklist_lock&lt;/span&gt;, which are atomic-context synchronisation primitives.&lt;/li&gt;&lt;li&gt;In &lt;span style="font-family:courier new;"&gt;fork()&lt;/span&gt;, the new thread is added to the list with &lt;span style="font-family:courier new;"&gt;tasklist_lock&lt;/span&gt; held, though cgroup modifications are done outside of that lock.&lt;/li&gt;&lt;li&gt;In &lt;span style="font-family:courier new;"&gt;exit()&lt;/span&gt;, the &lt;span style="font-family:courier new;"&gt;tsk-&amp;gt;PF_EXITING&lt;/span&gt;  flag is set, and later, the thread falls off of the list (under RCU).  It is unclear what happens to the other threads in a group when its  leader exits, but it seems possible for them to stick around.&lt;/li&gt;&lt;li&gt;In &lt;span style="font-family:courier new;"&gt;exec()&lt;/span&gt;, if the process is multithreaded, the calling thread will kill all other threads in the group (by way of &lt;span style="font-family:courier new;"&gt;zap_other_threads()&lt;/span&gt;, which delivers a &lt;span style="font-family:courier new;"&gt;SIGKILL&lt;/span&gt;). Further, if the calling thread is not the group leader, it will &lt;a href="http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/fs/exec.c#L828"&gt;steal group leadership&lt;/a&gt;  from the current leader. The old leader's leader pointer is updated,  but other threads' are not, because they are going away - though they  may not necessarily fall off of the group list until their signal is  processed!&lt;/li&gt;&lt;li&gt;For any &lt;span style="font-family:courier new;"&gt;task_struct&lt;/span&gt;, you can grab a reference on it to prevent it from being freed with &lt;span style="font-family:courier new;"&gt;get_task_struct()&lt;/span&gt;. This does not prevent the task from exiting, nor does it prevent it from falling off of the thread list.&lt;/li&gt;&lt;/ol&gt;I spent a long time scrambling around trying to do every per-thread operation in &lt;span style="font-family:courier new;"&gt;cgroup_attach_proc()&lt;/span&gt; (my operation) while in RCU read-side. Since you're &lt;a href="http://cgrouphacking.blogspot.com/2011/02/atomic-all-nighters.html"&gt;not allowed&lt;/a&gt; to do any blocking operation while in an atomic context, this led me to much yak-shaving, tracking down things like open-coded calls to &lt;span style="font-family:courier new;"&gt;schedule()&lt;/span&gt; and NUMA memory migrations (erk!). I realised the best way was simply to &lt;span style="font-family:courier new;"&gt;kmalloc()&lt;/span&gt; an array as big as the threadgroup, snapshot refcounted pointers for each &lt;span style="font-family:courier new;"&gt;task_struct&lt;/span&gt; into it, and iterate over that instead.  Still, since this requires dynamic memory allocation, we need to drop all locks which might protect the thread list between when we obtain a reference on the leader and when we go to iterate over his group list. (This will be important later.)&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family:courier new;"&gt;fork()&lt;/span&gt; problem is obvious: a race between a forking thread (using &lt;span style="font-family:courier new;"&gt;CLONE_THREAD&lt;/span&gt;) and &lt;span style="font-family:courier new;"&gt;cgroup_attach_proc()&lt;/span&gt; may cause the new thread to be left in the old cgroup if the latter happens between when &lt;span style="font-family:courier new;"&gt;fork()&lt;/span&gt; copies the parent thread's old cgroups pointer and when it adds the thread to the tasklist. I solved this by using an rwlock (called "&lt;span style="font-family:courier new;"&gt;rwsem&lt;/span&gt;" in linux-land) which forking threads take in read-mode. There is an issue here, though: &lt;span style="font-family:courier new;"&gt;fork()&lt;/span&gt; is such a hot-path that introducing any shared memory access is dubious, and taking an extra lock (even in read mode!) entails writing to shared memory. The performance regression appears when multiple processors contend for the memory: they have to synchronise their caches, and possibly &lt;a href="http://www.google.com/search?q=cache+line+bouncing"&gt;shoot down&lt;/a&gt; the other's entry. There is not much to be done about this if you need to take a lock (almost true: in linux-2.4, there used to exist &lt;a href="http://lwn.net/Articles/378911/"&gt;big-reader locks&lt;/a&gt; for solving this problem), so we simply seek to place our lock in memory that is already contended for. Fortunately, the &lt;span style="font-family:courier new;"&gt;signal_struct&lt;/span&gt; is shared among the group, has an appropriate lifespan, and has a reference counter that already bounces.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family:courier new;"&gt;exec()&lt;/span&gt; problem is somewhat more subtle. Recall from above that we need to drop all locks before allocating an array to snapshot the threadgroup into - when we originally found the &lt;span style="font-family:courier new;"&gt;task_struct&lt;/span&gt; to do our operation on, we knew that it was the leader, but what if when we drop locks before allocating, some other thread does &lt;span style="font-family:courier new;"&gt;exec()&lt;/span&gt; and steals leadership from us? Other threads in the group may exit, causing our links in the threadgroup list to become invalid, making iterating over the group unsafe. Furthermore, since the only thread we hold a reference on is the original thread, we can't even guarantee that following our updated &lt;span style="font-family:courier new;"&gt;tsk-&amp;gt;group_leader&lt;/span&gt; pointer is safe.&lt;br /&gt;&lt;br /&gt;Hence, the only safe way to snapshot the whole threadgroup after allocating an array big enough to do so is to not only take the RCU lock, but also to re-check whether we are still the group leader after doing so. If we are, then the group list is safe to iterate over, but if we are not, we must drop everything and start over - to look up by TGID whoever is the leader of the group (if it even still exists) again. So we have a check for the threadgroup leader when finding his &lt;span style="font-family:courier new;"&gt;task_struct&lt;/span&gt; to begin with, another check for the consistency of the list upon entering the RCU critical section for the second time, and a loop around the whole thing that retries for as long as it takes for no &lt;span style="font-family:courier new;"&gt;exec()&lt;/span&gt; race to occur. I call this algorithm "&lt;span style="font-weight: bold;"&gt;double-double-toil-and-trouble-check locking&lt;/span&gt;".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-1130408375784903985?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/1130408375784903985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2011/04/double-double-toil-and-trouble-check.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/1130408375784903985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/1130408375784903985'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2011/04/double-double-toil-and-trouble-check.html' title='double-double-toil-and-trouble-check locking'/><author><name>Ben</name><uri>http://www.blogger.com/profile/00057900193141052120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-3629510508945976639</id><published>2011-02-18T21:58:00.008-05:00</published><updated>2011-02-18T23:28:10.111-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='threadgroup'/><category scheme='http://www.blogger.com/atom/ns#' term='locking'/><title type='text'>atomic all-nighters</title><content type='html'>&lt;span style="font-weight: bold;"&gt;exposition&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In an environment like the Linux kernel, the many ways to deal with concurrency cause a bunch of restrictions on what sorts of things you can do at certain points in your code. The concurrency primitives are, briefly:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;mutexes/semaphores: high-level blocking locks, will deschedule you if you need to wait to get it. Very commonly used in many subsystems, to protect data structures, and so on (popular example: &lt;span style="font-family:courier new;"&gt;tsk-&gt;mmap_sem&lt;/span&gt;).&lt;/li&gt;&lt;li&gt;spinlocks/RCU: low-level "atomic context" locks, will disable interrupts and spin-wait (in the SMP case). Shouldn't be held around "very expensive" operations (at the very least because another CPU may be spin-waiting on you!). These are needed for, among other reasons, accessing things from an interrupt handler, wherein rescheduling is already not permitted. The global &lt;span style="font-family:courier new;"&gt;tasklist_lock&lt;/span&gt; is a spin-lock, as are the locks on each &lt;span style="font-family:courier new;"&gt;task_struct&lt;/span&gt; (&lt;span style="font-family:courier new;"&gt;task_lock(tsk)&lt;/span&gt;).&lt;/li&gt;&lt;li&gt;There are calls such as &lt;span style="font-family:courier new;"&gt;yield()&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;schedule()&lt;/span&gt; (and &lt;span style="font-family:courier new;"&gt;sleep()&lt;/span&gt;, ewwww) which explicitly invoke the scheduler, and are sometimes used in open-coded synchronisation dances (to varying stylistic quality) (examples: &lt;a href="http://lxr.linux.no/#linux+v2.6.36/kernel/exit.c#L644"&gt;A&lt;/a&gt; and &lt;a href="http://lxr.linux.no/#linux+v2.6.36/kernel/exit.c#L1603"&gt;B&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;Also of note is the dynamic memory allocator, &lt;span style="font-family:courier new;"&gt;kmalloc(size_t size, gfp_t flags)&lt;/span&gt;. The &lt;a href="http://lxr.linux.no/#linux+v2.6.36/include/linux/gfp.h"&gt;flags&lt;/a&gt; argument controls the behaviour of the allocator - the two most common choices:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;GFP_KERNEL&lt;/span&gt;: indicates that it's okay to wait and reschedule if necessary&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;GFP_ATOMIC&lt;/span&gt;: "please satisfy this request immediately", and therefore more likely to fail - incidentally, this may also allocate from the kernel's "emergency memory pool", under the assumption that it should end up freed quickly.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;There is also &lt;span style="font-family:courier new;"&gt;vmalloc(...)&lt;/span&gt;, which allocates through the VM, and is therefore even more reliable especially for very large contiguous chunks of memory - but also always may sleep in order to complete the request.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;You might by this point have figured out the rule, which is that you're &lt;span style="font-style: italic;"&gt;not allowed to invoke the scheduler&lt;/span&gt; from within an atomic context (i.e. holding a spin-lock / interrupts are disabled / etc), or the world will explode. As a consequence, if you want to lock something while holding another spin-lock, it had better also be protected by a spin-lock (or by RCU); if you want to reliably dynamically allocate memory while juggling a bunch of locks, you'd better not do it while holding anything lower-level than a mutex or semaphore.&lt;br /&gt;&lt;br /&gt;There were a bunch of places along the way of implementing the &lt;a href="http://lkml.org/lkml/2011/2/7/418"&gt;cgroups threadgroup interface patches&lt;/a&gt; where I had to tread carefully around my concurrency primitives to not break this rule. There's a macro in linux called "&lt;span style="font-family:courier new;"&gt;might_sleep()&lt;/span&gt;" which you can drop in your scheduler-invoking code as a debugging measure, and it will do a runtime check that everything is OK when it gets hit (there's even a "&lt;span style="font-family:courier new;"&gt;might_sleep_if(...)&lt;/span&gt;" version). But (a) the developer has to think to put it there, and developers are unreliable, and (b) it's a runtime check for something that seems like a static property of the code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;an idea&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So it occurred to me that maybe there should be machinery as part of a language's tool-chain that could automatically verify whether code respects the contexts that functions are supposed to run in. It could even be entirely separate from the compiler itself (I was thinking that it might not be too hard to extend my 411 compiler to do it, though all the changes would be in my partner's code, not mine, so). The framework might look something like this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Independent of the code, a definition of the various contexts that are important to track (and the rules governing their interactions). Here, an individual function could be "&lt;span style="font-family:courier new;"&gt;MIGHT_SLEEP&lt;/span&gt;" or "&lt;span style="font-family:courier new;"&gt;DOESNT_SLEEP&lt;/span&gt;", and call sites (or, regions of code in general) will have a property like "&lt;span style="font-family:courier new;"&gt;MAY_SLEEP&lt;/span&gt;" or "&lt;span style="font-family:courier new;"&gt;MUSTNT_SLEEP&lt;/span&gt;". If a &lt;span style="font-family:courier new;"&gt;MIGHT_SLEEP&lt;/span&gt; function is called from a &lt;span style="font-family:courier new;"&gt;MUSTNT_SLEEP&lt;/span&gt; line of code, print an error message; all other cases are okay. Functions may also change the context at their call sites, so transitions may be specified.&lt;/li&gt;&lt;li&gt;Explicitly annotate those functions which affect the code context:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;schedule()&lt;/span&gt;, as the central function that everything sleeping goes through, should be marked &lt;span style="font-family:courier new;"&gt;MIGHT_SLEEP&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;preempt_disable()&lt;/span&gt;, which spinlocks and RCU et al. invoke, should transition the call site from &lt;span style="font-family:courier new;"&gt;MAY_SLEEP&lt;/span&gt; to &lt;span style="font-family:courier new;"&gt;MUSTNT_SLEEP&lt;/span&gt;, and &lt;span style="font-family:courier new;"&gt;preempt_enable()&lt;/span&gt;, its dual, turns &lt;span style="font-family:courier new;"&gt;MUSTNT_SLEEP&lt;/span&gt; into &lt;span style="font-family:courier new;"&gt;MAY_SLEEP&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;To a certain extent, the tool can then infer context rules for all other functions in the program. ("&lt;span style="font-family:courier new;"&gt;spin_lock&lt;/span&gt; calls &lt;span style="font-family:courier new;"&gt;preempt_disable&lt;/span&gt;, and &lt;span style="font-family:courier new;"&gt;task_lock&lt;/span&gt; calls &lt;span style="font-family:courier new;"&gt;spin_lock&lt;/span&gt;, and &lt;span style="font-family:courier new;"&gt;do_stuff&lt;/span&gt; calls &lt;span style="font-family:courier new;"&gt;task_lock&lt;/span&gt; on line 7, so after line 7 the code is &lt;span style="font-family:courier new;"&gt;MUSTNT_SLEEP&lt;/span&gt;; on line 8 &lt;span style="font-family:courier new;"&gt;do_stuff&lt;/span&gt; calls &lt;span style="font-family:courier new;"&gt;kmalloc&lt;/span&gt;, which ... &lt;span style="font-family:courier new;"&gt;MAY_SLEEP&lt;/span&gt;, so the code is wrong.") But also you don't want to infer over the whole codebase, so it would also be wise to annotate (where you can) function prototypes in your headers as &lt;span style="font-family:courier new;"&gt;MIGHT_SLEEP&lt;/span&gt; or &lt;span style="font-family:courier new;"&gt;DOESNT_SLEEP&lt;/span&gt; where appropriate.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sometimes code likes to have callback interfaces, so structs full of function pointers may be built and passed around. A function pointer interface should be specified the same way as a call site (&lt;span style="font-family:courier new;"&gt;MAY_SLEEP&lt;/span&gt; or &lt;span style="font-family:courier new;"&gt;MUSTNT_SLEEP&lt;/span&gt;) and then checked at every point where a function's address is taken to serve as such a pointer.&lt;/li&gt;&lt;li&gt;Actually, some common programming idioms make it hard to say if a function just by name will block or not - like with &lt;span style="font-family:courier new;"&gt;kmalloc&lt;/span&gt; (as described above), which &lt;span style="font-family:courier new;"&gt;MIGHT_SLEEP&lt;/span&gt; if you say &lt;span style="font-family:courier new;"&gt;GFP_KERNEL&lt;/span&gt;, but &lt;span style="font-family:courier new;"&gt;DOESNT_SLEEP&lt;/span&gt; if you say &lt;span style="font-family:courier new;"&gt;GFP_ATOMIC&lt;/span&gt;. So some functions need to be described like &lt;span style="font-family:courier new;"&gt;MIGHT_SLEEP_IF(ARG(2) == GFP_KERNEL)&lt;/span&gt;.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Functions which take, say, a flags argument to pass through to a &lt;span style="font-family:courier new;"&gt;kmalloc&lt;/span&gt; call will also be &lt;span style="font-family:courier new;"&gt;MIGHT_SLEEP_IF&lt;/span&gt;; the condition would have to propagate.&lt;/li&gt;&lt;li&gt;Usually the flag's value is known at compile time; if it's not known (and you're in a &lt;span style="font-family:courier new;"&gt;MUSTNT_SLEEP&lt;/span&gt; section) then the code is of dubious quality anyway and should be errored on.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;This is remarkably like &lt;a href="http://www.cs.cmu.edu/%7Ealdrich/papers/onward2009-state.pdf"&gt;typestate&lt;/a&gt;, only the stateful object is the code itself. If you imagine every function as additionally passing around a single global object (per-CPU, actually) that represents the execution context, it is basically identical, except the matching conditions are more complicated than typestate's canonical examples.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;but actuall&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;y&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There is one big problem, which is that &lt;span style="font-family:courier new;"&gt;preempt_disable()&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;preempt_enable()&lt;/span&gt; are actually &lt;span style="font-family:courier new;"&gt;inc_preempt_count()&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;dec_preempt_count()&lt;/span&gt;, and spinlocks can nest. So saying that every time you &lt;span style="font-family:courier new;"&gt;spin_unlock()&lt;/span&gt; you transition into a &lt;span style="font-family:courier new;"&gt;MAY_SLEEP&lt;/span&gt; section misses some of the point! Instead, the context should be a more complicated state-space (in this limited application, a counter will suffice, but it's easy to see how it could have as many fields of as many types as you want). Now the annotations attached to each function are turning into veritable functions on their own... Some accurate rules might look as follows:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The context of any range of code is an &lt;span style="font-family:courier new;"&gt;Int&lt;/span&gt;, with &lt;span style="font-family:courier new;"&gt;0&lt;/span&gt; indicating that sleeping is allowed.&lt;/li&gt;&lt;li&gt;The annotation for any function is, generally, an &lt;span style="font-family:courier new;"&gt;Int -&gt; Bool&lt;/span&gt;. For this application, they would be simply either:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"&lt;span style="font-family:courier new;"&gt;const True&lt;/span&gt;" (alias "&lt;span style="font-family:courier new;"&gt;DOESNT_SLEEP&lt;/span&gt;"): calling this is always safe&lt;/li&gt;&lt;li&gt;"&lt;span style="font-family:courier new;"&gt;== 0&lt;/span&gt;" (alias "&lt;span style="font-family:courier new;"&gt;MIGHT_SLEEP&lt;/span&gt;"): only safe if sleeping is permitted As per point #5 above, the annotation may also refer to the function's arguments, so for &lt;span style="font-family:courier new;"&gt;kmalloc&lt;/span&gt;, it would be something like "&lt;span style="font-family:courier new;"&gt;(\x -&gt; ARG(2) == GFP_ATOMIC || x == 0)&lt;/span&gt;".&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;An extra annotation indicating changing the context (&lt;span style="font-family:courier new;"&gt;Int -&gt; Int&lt;/span&gt;) may be provided (or inferred). For &lt;span style="font-family:courier new;"&gt;inc_preempt_count()&lt;/span&gt;, it would be "&lt;span style="font-family:courier new;"&gt;+ 1&lt;/span&gt;", and for &lt;span style="font-family:courier new;"&gt;dec_preempt_count()&lt;/span&gt;, it would be "&lt;span style="font-family:courier new;"&gt;- 1&lt;/span&gt;".&lt;/li&gt;&lt;li&gt;Propagation and inference would be a bunch of boolean intersection and function composition. There would certainly be some room to coalesce conditions to avoid redundant condition blow-up, but at some point it would probably be acceptable for the analysis tool to say "this is too much for me to follow, please annotate explicitly".&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;For such a tool to be possibly useful, it would need to be easy to phase in to an existing codebase. You can't expect every developer who ever wrote code to come back and annotate every function (especially if they're uninteresting!), and you can't do it yourself, but you don't want to have to churn context inference for an hour over a 10000-node call graph every time you modify one function. So it should start with some reasonable defaults: assume that things that are unannotated are safe (all functions behave as &lt;span style="font-family:courier new;"&gt;DOESNT_SLEEP&lt;/span&gt;, all unknown code ranges &lt;span style="font-family:courier new;"&gt;MAY_SLEEP&lt;/span&gt;), so "some problems may go unnoticed, but if we say there's an error, then there is one for sure". Inference can probably be done little bits at a time on each module, and the tool could even spit out auto-generated annotations (subject to hand-review) to go in the corresponding header files to make easy bringing the codebase up to speed.&lt;br /&gt;&lt;br /&gt;Well, then.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-3629510508945976639?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/3629510508945976639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2011/02/atomic-all-nighters.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/3629510508945976639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/3629510508945976639'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2011/02/atomic-all-nighters.html' title='atomic all-nighters'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-7473551347938885194</id><published>2010-12-26T07:17:00.009-05:00</published><updated>2010-12-26T07:46:43.706-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='threadgroup'/><category scheme='http://www.blogger.com/atom/ns#' term='mmotm'/><category scheme='http://www.blogger.com/atom/ns#' term='locking'/><title type='text'>lesson: never hack when it won't solve the entire problem.</title><content type='html'>I'd like to share some code I wrote for a particularly misguided solution to a yak-shaving quest. Fortunately, soon afterwards, I realized a much better way to dodge the bullet that I was here trying to take in the chest and stagger back to camp while screaming for help... so this code will never see the light of day.&lt;br /&gt;&lt;br /&gt;That's good, because I also think it has a fatal flaw. I won't say it, but I'll give an exposition so you can figure it out. Here's the idea:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You are not allowed to block, sleep, or otherwise yield while in an "atomic" section of code (usually because it means interrupts are disabled). In order to safely iterate over a thread-group, you need to hold either &lt;span style="font-family:courier new;"&gt;rcu_read_lock&lt;/span&gt; or &lt;span style="font-family:courier new;"&gt;tasklist_lock&lt;/span&gt;, both of which are low-level locks and constitute "atomic" code while being held.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In &lt;span style="font-family:courier new;"&gt;kernel/cpuset.c&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;cpuset_change_task_nodemask&lt;/span&gt; has two steps, and a check between those steps which does a &lt;span style="font-family:courier new;"&gt;yield&lt;/span&gt; to synchronize its internal state &lt;span style="font-size:85%;"&gt;(as part of an open-coded replacement for a proper concurrency primitive... ugh. from commi&lt;/span&gt;&lt;span style="font-size:85%;"&gt;t c0ff7453bb5c7c98e0885fb94279f2571946f280 on mmotm)&lt;/span&gt;. Here I have changed it to return &lt;span style="font-family:courier new;"&gt;-EAGAIN&lt;/span&gt; instead of yielding, so the caller can synchronize "more appropriately".&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;get_task_struct&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;put_task_struct&lt;/span&gt; manage a thread's reference count. After you've done &lt;span style="font-family:courier new;"&gt;get_task_struct&lt;/span&gt;, it will always be safe to access that memory, until you release it. If you call &lt;span style="font-family:courier new;"&gt;put_task_struct&lt;/span&gt; and you're the last one with a reference count, it does a bunch of cleanup. (interesting read &lt;a href="http://linux.derkeiler.com/Mailing-Lists/Kernel/2006-09/msg07725.html"&gt;here&lt;/a&gt;, perhaps a hint.)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;1456&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1457&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* This particular per-task operation requires being able to sleep, so&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1458&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* it can't be done in the attach_task callback, where sleeping is&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1459&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* forbidden. See cgroup_attach_proc.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1460&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1461&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (threadgroup) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1462&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct task_struct *c = NULL;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1463 again:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1464&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rcu_read_lock();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1465&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* ensure safe thread-group traversal */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1466&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (thread_group_leader(tsk)) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1467&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list_for_each_entry_rcu(c, &amp;amp;tsk-&gt;thread_group,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1468&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; thread_group) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1469&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get_task_struct(c);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1470&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = cpuset_change_task_nodemask(c,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1471&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;cpuset_attach_nodemask_to);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1472&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1473&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* on a failed nodemask change, we need to exit&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1474&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* the atomic section and start over.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1475&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1476&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ret == -EAGAIN) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1477&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rcu_read_unlock();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1478&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1479&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto again;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1480&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1481&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; put_task_struct(c);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1482&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1483&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rcu_read_unlock();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1484&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else if (c != NULL) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1485&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1486&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* if racing with exec caused an abort, we need to&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1487&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* finish the rebind operation in progress on it.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1488&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1489&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rcu_read_unlock();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1490&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1491&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = cpuset_change_task_nodemask(c,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1492&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;cpuset_attach_nodemask_to);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1493&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ret == -EAGAIN)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1494&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1495&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } while (ret != -EAGAIN)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1496&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; put_task_struct(c);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1497&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1498&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1499&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1500&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = cpuset_change_task_nodemask(tsk,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1501&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;cpuset_attach_nodemask_to);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1502&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ret == -EAGAIN)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1503&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1504&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } while (ret != -EAGAIN);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1505&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-7473551347938885194?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/7473551347938885194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2010/12/lesson-never-hack-when-it-wont-solve.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7473551347938885194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7473551347938885194'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2010/12/lesson-never-hack-when-it-wont-solve.html' title='lesson: never hack when it won&apos;t solve the entire problem.'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-8464522410732324908</id><published>2010-12-25T05:33:00.003-05:00</published><updated>2010-12-25T05:49:56.680-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='threadgroup'/><category scheme='http://www.blogger.com/atom/ns#' term='locking'/><title type='text'>as though holding a red pen and a lock stamp</title><content type='html'>Found two bugs in peripheral code around &lt;span style="font-family:courier new;"&gt;cgroup_attach_task&lt;/span&gt; while trying to finish up my older project, which is to add &lt;span style="font-family:courier new;"&gt;cgroup_attach_proc&lt;/span&gt;. More on the actual project later; for now:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Earlier this year, &lt;span style="font-family:courier new;"&gt;cpuset&lt;/span&gt; was changed to use &lt;span style="font-family:courier new;"&gt;NODEMASK_ALLOC&lt;/span&gt;, to avoid stack-allocating a structure which can be huge on NUMA systems. However, the present usage is &lt;a href="http://www.spinics.net/lists/linux-containers/msg22223.html"&gt;rather cavalier&lt;/a&gt; in functions that aren't allowed to fail!&lt;/li&gt;&lt;li&gt;Last month, the locking order in &lt;span style="font-family:courier new;"&gt;memcontrol&lt;/span&gt; was changed to avoid a potential deadlock... introducing a bit of &lt;a href="http://www.spinics.net/lists/linux-containers/msg22236.html"&gt;foot-stepping&lt;/a&gt; between it and &lt;span style="font-family:courier new;"&gt;cpuset&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Fortunately, none of these are design-level blockers to the patch series I'm trying to finalize. But the solutions could prove "interesting"...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-8464522410732324908?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/8464522410732324908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2010/12/as-though-holding-red-pen-and-lock.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/8464522410732324908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/8464522410732324908'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2010/12/as-though-holding-red-pen-and-lock.html' title='as though holding a red pen and a lock stamp'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-8201667420227617987</id><published>2010-03-23T13:42:00.003-04:00</published><updated>2010-03-23T14:46:23.626-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Mainline</title><content type='html'>&lt;a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=220bf991b0366cc50a94feede3d7341fa5710ee4"&gt;2.6.34-rc2&lt;/a&gt; came out three days ago, and supports modular cgroup subsystems.&lt;br /&gt;&lt;br /&gt;(The &lt;span style="font-family:courier new;"&gt;net_cls&lt;/span&gt; patch wasn't merged with the rest and is presently still running the approval gauntlet, though even &lt;span style="font-family: courier new;"&gt;blkio-cg&lt;/span&gt; is already in.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-8201667420227617987?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/8201667420227617987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2010/03/mainline.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/8201667420227617987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/8201667420227617987'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2010/03/mainline.html' title='Mainline'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-7677002239973958261</id><published>2010-01-07T22:59:00.003-05:00</published><updated>2010-01-07T23:10:24.529-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='gdb'/><title type='text'>gdb is not so great at debugging within modules.</title><content type='html'>&lt;span style="font-family: courier new;"&gt;&lt;span style="font-family: georgia;"&gt;At the suggestion of LKML, I have spent today working on making blk-cgroup, also known as blkiocg, into a module. it has not gone entirely smoothly, as there is an already existing module (cfq-iosched) that depends on it, so the process has involved a good amount of figuring out how module dependencies (in terms of symbol-loading and the language of the kbuild system) work.&lt;br /&gt;&lt;br /&gt;Now that I got it finally to build, boot, and load the modules (modprobe even figured out the dependency for me, it was great), I discovered that the kernel panics when trying to unload the subsystem (with what looks like a SIGILL in some memory management code). So, GDBing it up, I have discovered that it is difficult to deal with code that's loaded at runtime that isn't a standard dynamic library.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(gdb)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;0x000000006005146a      3504            ss-&gt;destroy(ss, dummytop);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(gdb)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;0x00000000628202ad in ?? ()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(gdb) break block/blk-cgroup.c:207&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;No source file named block/blk-cgroup.c.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Make breakpoint pending on future shared library load? (y or [n]) n&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(gdb) disassemble 0x628202ad&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;No function contains specified address.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(gdb) disassemble 0x628202ad 0x62820363&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Dump of assembler code from 0x628202ad to 0x62820363:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;0x00000000628202ad:     push   %rbp&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And you thought 213's bomblab would never be useful!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-7677002239973958261?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/7677002239973958261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2010/01/gdb-is-not-so-great-at-debugging-within.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7677002239973958261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7677002239973958261'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2010/01/gdb-is-not-so-great-at-debugging-within.html' title='gdb is not so great at debugging within modules.'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-7119398698558305945</id><published>2009-12-31T00:44:00.001-05:00</published><updated>2009-12-31T01:05:33.779-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>lkml submission #4</title><content type='html'>http://lkml.org/lkml/2009/12/31/2&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-7119398698558305945?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/7119398698558305945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/lkml-submission-4.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7119398698558305945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7119398698558305945'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/lkml-submission-4.html' title='lkml submission #4'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-9094881655213054456</id><published>2009-12-21T16:45:00.002-05:00</published><updated>2009-12-21T16:45:47.962-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>lkml submission #3</title><content type='html'>&lt;a href="http://lkml.org/lkml/2009/12/21/211"&gt;http://lkml.org/lkml/2009/12/21/211&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-9094881655213054456?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/9094881655213054456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/lkml-submission-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/9094881655213054456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/9094881655213054456'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/lkml-submission-3.html' title='lkml submission #3'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-457004831432497091</id><published>2009-12-21T02:27:00.003-05:00</published><updated>2009-12-21T02:31:57.733-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='mmotm'/><category scheme='http://www.blogger.com/atom/ns#' term='locking'/><title type='text'>I take two refcounts before I take two refcounts, and then I take two more</title><content type='html'>The best solution to the previously mentioned deadlock problem was determined to be having parse_cgroupfs_options take module reference counts (before sget takes the lock), and have rebind_subsystems drop them later. This division of work makes sure that the subsystems will stick around during sget so we can safely drop our own lock in the meantime.&lt;br /&gt;&lt;br /&gt;So I was polishing up the deadlock-free version of the patch series today, and found a good bug. After a few routine changes and polishings, I decided to go through a bit more thorough testing than I'd done since implementing this change:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # mount -t cgroup none -o test2,net_cls,devices,cpuacct cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # ls cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup.procs&amp;nbsp;&amp;nbsp; cpuacct.usage_percpu&amp;nbsp;&amp;nbsp;devices.list&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; release_agent&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cpuacct.stat&amp;nbsp;&amp;nbsp; devices.allow&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; net_cls.classid&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tasks&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cpuacct.usage&amp;nbsp;&amp;nbsp;devices.deny&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;notify_on_release&amp;nbsp;&amp;nbsp;test2.hax&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # lsmod&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Module&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Size&amp;nbsp;&amp;nbsp;Used by&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup_test2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2880&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cls_cgroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5080&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev #&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Simple enough. Now, cgroups has this functionality where you can't destroy a hierarchy that has children cgroups. (Children cgroups are represented as subdirectories in the filesystem tree, and are made just as you would expect.) It does, however, let you unmount it:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # mkdir cgroup/foo&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # umount cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev #&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In which case the hierarchy sticks around, invisible. You can make it reappear by mounting with the same list of subsystems; any attempt to mount a subsystem on that hierarchy with a mismatched set of subsystems will fail.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # lsmod&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Module&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Size&amp;nbsp;&amp;nbsp;Used by&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup_test2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2880&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cls_cgroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5080&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev #&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Great - the modules' reference counts indicate that the hierarchy is still there. Let's bring it back again:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # mount -t cgroup none -o cpuacct,test2,net_cls,devices cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # lsmod&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Module&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Size&amp;nbsp;&amp;nbsp;Used by&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup_test2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2880&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cls_cgroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5080&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev #&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Oops! The mounting code didn't realize that we weren't changing anything with respect to the subsystems, and we leaked a reference! Fortunately, with the new changes that I made, there was a simple fix - in cgroup_get_sb, added lines 1518-1519:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1426&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (root == opts.new_root) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1427 +--- 85 lines: We used the new root structure, so this is a new hierarchy ---&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1512&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1513&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1514&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* We re-used an existing hierarchy - the new root (if&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1515&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* any) is not needed&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1516&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1517&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cgroup_drop_root(opts.new_root);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1518&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* no subsys rebinding, so refcounts don't change */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1519&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drop_parsed_module_refcounts(opts.subsys_bits);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1520&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For extra credit, tell how this bug is also a security vulnerability!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-457004831432497091?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/457004831432497091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/i-take-two-refcounts-before-i-take-two.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/457004831432497091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/457004831432497091'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/i-take-two-refcounts-before-i-take-two.html' title='I take two refcounts before I take two refcounts, and then I take two more'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-1974372255729771453</id><published>2009-12-09T03:04:00.004-05:00</published><updated>2009-12-09T03:51:32.865-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='locking'/><title type='text'>I learned something new today.</title><content type='html'>&lt;a href="http://lkml.org/lkml/2009/12/9/30"&gt;http://lkml.org/lkml/2009/12/9/30&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One possible solution - modify cgroup_get_sb to do as follows:&lt;br /&gt;&lt;br /&gt;1) get &lt;span style="font-family:courier new;"&gt;subsys_mutex&lt;/span&gt;&lt;br /&gt;2) &lt;span style="font-family:courier new;"&gt;parse_cgroupfs_options()&lt;br /&gt;&lt;/span&gt;3) release &lt;span style="font-family:courier new;"&gt;subsys_mutex&lt;/span&gt;&lt;br /&gt;4) call &lt;span style="font-family:courier new;"&gt;sget()&lt;/span&gt;, which gets &lt;span style="font-family:courier new;"&gt;s-&gt;s_umount&lt;/span&gt;&lt;br /&gt;5) get subsys_mutex again&lt;br /&gt;6) &lt;span style="font-family:courier new;"&gt;verify_cgroupfs_options&lt;/span&gt; - also known as the "deadlock avoidance dance"&lt;br /&gt;7) proceed.&lt;br /&gt;&lt;br /&gt;Now, note, for clarification:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1508 static struct file_system_type cgroup_fs_type = {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1509 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.name = "cgroup",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1510 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.get_sb = cgroup_get_sb,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1511 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.kill_sb = cgroup_kill_sb,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1512 };&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The issue is that &lt;span style="font-family:courier new;"&gt;s-&gt;s_umount&lt;/span&gt; is taken in &lt;span style="font-family:courier new;"&gt;get_sb&lt;/span&gt; while it already has the &lt;span style="font-family:courier new;"&gt;subsys_mutex&lt;/span&gt;, whereas &lt;span style="font-family:courier new;"&gt;kill_sb&lt;/span&gt; is called with &lt;span style="font-family:courier new;"&gt;s-&gt;s_umount&lt;/span&gt; already held, and deadlock comes from there. There's a good question lurking here, and it is "Who ever designed an interface of seemingly symmetrical functions, one of which has to take a lock inside it while the other has the lock taken before it's called?"&lt;br /&gt;&lt;br /&gt;So yes, there's locking order violation, but if functions were locks (which is a reasonable comparison because isn't it intuitive to have a function that takes a lock at the start and drops it at the end?) then the blame would be on whoever wrote this interface to begin with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-1974372255729771453?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/1974372255729771453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/i-learned-something-new-today.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/1974372255729771453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/1974372255729771453'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/i-learned-something-new-today.html' title='I learned something new today.'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-544550392216027172</id><published>2009-12-04T04:03:00.001-05:00</published><updated>2009-12-04T04:03:50.726-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>lkml submission #2</title><content type='html'>&lt;a href="http://lkml.org/lkml/2009/12/4/53"&gt;http://lkml.org/lkml/2009/12/4/53&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-544550392216027172?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/544550392216027172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/lkml-submission-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/544550392216027172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/544550392216027172'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/lkml-submission-2.html' title='lkml submission #2'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-5073390929046882992</id><published>2009-12-03T00:08:00.003-05:00</published><updated>2009-12-03T01:54:21.234-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><title type='text'>so what's this net_cls thing actually useful for?</title><content type='html'>Anand came to #cslounge today with an interesting question:&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt; &lt;/span&gt;is there a logical equivalent of nice for network bandwidth management that i can easily apply to a process? I don't like being unable to browse the web or irc when I scp large amounts of stuff.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;I was under the impression that there didn't actually exist a subsystem for controlling that sort of thing, only for "classifying" it - the net_cls subsystem has one control file, which is "&lt;span style="font-family: courier new;"&gt;classid&lt;/span&gt;", and it lets you specify a network class for each cgroup, and it doesn't seem to do much because it doesn't have anything hooking into it because it's a module. Then I found &lt;a href="http://lkml.org/lkml/2008/1/23/50"&gt;this&lt;/a&gt;, which explains the actual secret: each classid can be associated with sockets held by tasks in those cgroups, and then from -userspace- have bandwidth throttling administered! Very slick, and keeps the kernel-side labour to a minimum, so much so that it can even be modularized.&lt;br /&gt;&lt;br /&gt;Of course, Anand's particular situation had an easier solution, which is the &lt;span style="font-family: courier new;"&gt;-l&lt;/span&gt; option to scp which lets you specify a bandwidth limit explicitly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-5073390929046882992?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/5073390929046882992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/so-whats-this-netcls-thing-actually.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/5073390929046882992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/5073390929046882992'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/12/so-whats-this-netcls-thing-actually.html' title='so what&apos;s this net_cls thing actually useful for?'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-550332978887372003</id><published>2009-11-16T00:20:00.003-05:00</published><updated>2009-11-16T01:03:38.454-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='mmotm'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>the cgroup infrastructure: a quick tour</title><content type='html'>throughout my work on cgroups I have had many moments in which I look at a struct definition or variable declaration or even a function call and have nothing to think but "uhhhhh??" there is a nontrivial amount of infrastructure in the cgroup world, and here I am going to attempt to do a quick run-through of how everything is set up.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;struct cgroupfs_root&lt;/span&gt;: this represents the root of a cgroup hierarchy. it knows things like what subsystems are attached to it, the root cgroup in the hierarchy, and other trivialities like its own name. variables of this type are almost always called "&lt;span style="font-family:courier new;"&gt;root&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;struct cgroup&lt;/span&gt;: represents a single cgroup. remember that each directory, looking through the VFS layer, is a cgroup, so when you '&lt;span style="font-family:courier new;"&gt;mkdir cgroup/foo&lt;/span&gt;', a new cgroup is created. variables of this type can be seen most commonly as "&lt;span style="font-family:courier new;"&gt;cgrp&lt;/span&gt;", but also sometimes "&lt;span style="font-family:courier new;"&gt;cg&lt;/span&gt;" or simply "&lt;span style="font-family:courier new;"&gt;c&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;struct cgroup_subsys&lt;/span&gt;: the heart of the subsystem API - function pointers for the subsystem's operations, and other various options. referred to usually simply as "&lt;span style="font-family:courier new;"&gt;ss&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;struct cgroup_subsys_state&lt;/span&gt;: per-cgroup, per-subsystem state storage - when you write to a subsystem control file for a given cgroup, this is what hears about it. always called "&lt;span style="font-family:courier new;"&gt;css&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;struct css_set&lt;/span&gt;: a collection of pointers to &lt;span style="font-family:courier new;"&gt;cgroup_subsys_state&lt;/span&gt; objects. each &lt;span style="font-family:courier new;"&gt;css_set&lt;/span&gt; is referenced by all tasks who use the given combination of subsystem states. any particular subsystem state for a given task is only likely to change if the task gets moved into a different cgroup in the hierarchy to which the subsystem is attached. the presence of these guys is purely an optimization, since multiple tasks can have the same combination of subsystem states, and will therefore use the same &lt;span style="font-family:courier new;"&gt;css_set&lt;/span&gt;. additionally, they are stored in a hashtable for quick access. in comments, this data structure is referred to as a "cgroup group", and variables tend to go by the name "&lt;span style="font-family:courier new;"&gt;cg&lt;/span&gt;", but sometimes "&lt;span style="font-family:courier new;"&gt;css&lt;/span&gt;" as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;struct cg_cgroup_link&lt;/span&gt;: as per the comment, this is a "link structure for associating css_set objects with cgroups". each of these has a pointer to one &lt;span style="font-family:courier new;"&gt;struct cgroup&lt;/span&gt; and to one &lt;span style="font-family:courier new;"&gt;struct css_set&lt;/span&gt;, and lives at the intersection of two lists: the first list, per cgroup, links all css_sets associated with that cgroup; the second, per css_set, links all cgroups associated with that css_set - forming, as is described in &lt;span style="font-family:courier new;"&gt;Documentation/cgroups/cgroups.txt&lt;/span&gt;, a "lattice". they are what you want to use if you want to iterate either all css_sets in a cgroup or all cgroups in a css_set, and respond mostly to "&lt;span style="font-family:courier new;"&gt;link&lt;/span&gt;" but sometimes "&lt;span style="font-family:courier new;"&gt;cgl&lt;/span&gt;".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-550332978887372003?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/550332978887372003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/cgroup-infrastructure-quick-tour.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/550332978887372003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/550332978887372003'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/cgroup-infrastructure-quick-tour.html' title='the cgroup infrastructure: a quick tour'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-7401505826416962305</id><published>2009-11-03T22:05:00.002-05:00</published><updated>2009-11-03T22:09:02.551-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><title type='text'>a module UNloading adventure...</title><content type='html'>I promised myself this morning that I would spend a "little" bit of time thinking about module unloading. An afternoon and half an evening later, I found myself with a newly written 175-line patch...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # insmod /mnt/host/cgroup_test1.ko&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # insmod /mnt/host/cgroup_test2.ko&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # modprobe cls_cgroup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # lsmod&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Module                  Size  Used by&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cls_cgroup              5064  0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cgroup_test2            2800  0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cgroup_test1            2800  0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # mount -t cgroup none -o net_cls,test2 cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # lsmod&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Module                  Size  Used by&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cls_cgroup              5064  1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cgroup_test2            2800  1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cgroup_test1            2800  0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # rmmod cgroup_test1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # rmmod cgroup_test2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ERROR: Module cgroup_test2 is in use&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # umount cgroup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # lsmod&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Module                  Size  Used by&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cls_cgroup              5064  0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cgroup_test2            2800  0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # rmmod cgroup_test2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev #&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It still has some FIXMEs, meaning I need to make sure there are no races where there might be races, but I am surprised at how easy that was.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-7401505826416962305?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/7401505826416962305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/module-unloading-adventure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7401505826416962305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7401505826416962305'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/module-unloading-adventure.html' title='a module UNloading adventure...'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-2248219033590226418</id><published>2009-11-03T14:55:00.008-05:00</published><updated>2009-11-03T22:10:40.813-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='mmotm'/><title type='text'>try_module_get vs delete_module</title><content type='html'>let me introduce you to my friend, whose name is &lt;span style="font-family:courier new;"&gt;try_module_get&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;478 static inline int try_module_get(struct module *module)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;479 {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;480 &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int ret = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;481&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;482&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (module) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;483&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned int cpu = get_cpu();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;484&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (likely(module_is_live(module))) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;485&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; local_inc(__module_ref_addr(module, cpu));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;486&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; trace_module_get(module, _THIS_IP_,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;487&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; local_read(__module_ref_addr(module, cpu)));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;488&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;489&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;490&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;491&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; put_cpu();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;492&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;493&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ret;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;494 }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;he lives in &lt;span style="font-family:courier new;"&gt;include/linux/module.h&lt;/span&gt;, and he will get a reference count on the module for you, unless its state flag is set to &lt;span style="font-family:courier new;"&gt;MODULE_STATE_GOING&lt;/span&gt;. the &lt;span style="font-family:courier new;"&gt;get_cpu&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;put_cpu&lt;/span&gt; are SMP macros that disable/enable preemption so you can have a valid &lt;span style="font-family:courier new;"&gt;smp_processor_id&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;great! now let's take a look over at a potential competitor, a system call in &lt;span style="font-family:courier new;"&gt;kernel/module.c&lt;/span&gt; by the name of &lt;span style="font-family:courier new;"&gt;delete_module&lt;/span&gt;. part of his code looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;853&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Stop the machine so refcounts can't move and disable module. */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;854&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = try_stop_module(mod, flags, &amp;amp;forced);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;855&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ret != 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;856&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto out;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;857&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;858&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Never wait if forced. */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;859&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!forced &amp;amp;&amp;amp; module_refcount(mod) != 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;860&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wait_for_zero_refcount(mod);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;he can assist you in two different styles. the most common one is the "remove module immediately", which is what happens with &lt;span style="font-family:courier new;"&gt;rmmod&lt;/span&gt; usually. in this case, the &lt;span style="font-family:courier new;"&gt;O_NONBLOCK&lt;/span&gt; flag is specified. &lt;span style="font-family:courier new;"&gt;try_stop_module&lt;/span&gt; wants to set &lt;span style="font-family:courier new;"&gt;MODULE_STATE_GOING&lt;/span&gt;, and will behave differently depending on this flag.&lt;br /&gt;&lt;br /&gt;if &lt;span style="font-family:courier new;"&gt;O_NONBLOCK&lt;/span&gt; is specified, &lt;span style="font-family:courier new;"&gt;try_stop_module&lt;/span&gt; will apply a very big hammer whose name is &lt;span style="font-family:courier new;"&gt;stop_machine&lt;/span&gt;. in this case, it will safely ensure that the reference count is zero (failing otherwise), and then set the &lt;span style="font-family:courier new;"&gt;MODULE_STATE_GOING&lt;/span&gt; flag. this is wonderful: because of the &lt;span style="font-family:courier new;"&gt;stop_machine&lt;/span&gt; hammer, there will be no problems racing with our first friend, &lt;span style="font-family:courier new;"&gt;try_module_get&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;there is another way to invoke &lt;span style="font-family:courier new;"&gt;rmmod&lt;/span&gt;, which is with the &lt;span style="font-family:courier new;"&gt;--wait&lt;/span&gt; flag. if this is specified, &lt;span style="font-family:courier new;"&gt;try_stop_module&lt;/span&gt; will set &lt;span style="font-family:courier new;"&gt;MODULE_STATE_GOING&lt;/span&gt; without worrying about the refcount, and then &lt;span style="font-family:courier new;"&gt;delete_module&lt;/span&gt; will wait for the reference count to drop to zero. the keen-eyed systems hacker will at this point worry, what if we get the following scheduling pattern?&lt;br /&gt;&lt;br /&gt;0) module state = &lt;span style="font-family:courier new;"&gt;MODULE_STATE_LIVE&lt;/span&gt;; refcount = &lt;span style="font-family:courier new;"&gt;0&lt;/span&gt;&lt;br /&gt;1) &lt;span style="font-family:courier new;"&gt;try_module_get&lt;/span&gt; checks module is alive, and succeeds (line 484)&lt;br /&gt;2) &lt;span style="font-family:courier new;"&gt;delete_module&lt;/span&gt; sets &lt;span style="font-family:courier new;"&gt;MODULE_STATE_GOING&lt;/span&gt; flag (line 854)&lt;br /&gt;3) &lt;span style="font-family:courier new;"&gt;delete_module&lt;/span&gt; waits until the refcount is zero, and finishes (line 860)&lt;br /&gt;4) &lt;span style="font-family:courier new;"&gt;try_module_get&lt;/span&gt; increments the refcount (line 485).&lt;br /&gt;&lt;br /&gt;not to worry, keen-eyed systems hacker! you will note that our clever friend &lt;span style="font-family:courier new;"&gt;try_module_get&lt;/span&gt; disables preemption on its CPU as it runs. this guarantees that he will not be descheduled during that bit of his code, and therefore, through the wonderful phenomenon of "very small critical section", the problematic execution order won't happen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-2248219033590226418?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/2248219033590226418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/trymoduleget-vs-deletemodule.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/2248219033590226418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/2248219033590226418'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/trymoduleget-vs-deletemodule.html' title='try_module_get vs delete_module'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-2743993266522993221</id><published>2009-11-02T16:50:00.003-05:00</published><updated>2009-11-02T16:54:48.853-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><title type='text'>lkml submission #1</title><content type='html'>&lt;a href="http://lkml.org/lkml/2009/11/2/442"&gt;http://lkml.org/lkml/2009/11/2/442&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-2743993266522993221?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/2743993266522993221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/lkml-submission-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/2743993266522993221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/2743993266522993221'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/lkml-submission-1.html' title='lkml submission #1'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-573777879715475416</id><published>2009-11-02T15:52:00.002-05:00</published><updated>2009-11-02T15:56:27.108-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><title type='text'>"This is mainly for kernel developers and desperate users."</title><content type='html'>I ran into the &lt;span style="font-family: courier new;"&gt;CONFIG_MODULES_FORCE_UNLOAD&lt;/span&gt; option today, and out of curiosity tried setting it and seeing what would happen.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # rmmod -f cls_cgroup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Disabling lock debugging due to kernel taint&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # ls cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cgroup.procs  net_cls.classid  notify_on_release  release_agent  tasks&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # cat cgroup/net_cls.classid&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;cat: cgroup/net_cls.classid: Invalid argument&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # echo 1 &gt; cgroup/net_cls.classid&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;bash: echo: write error: Invalid argument&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # umount cgroup&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Modules linked in: [last unloaded: cls_cgroup]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Kernel panic - not syncing: Kernel mode fault at addr 0x0, ip 0x6017b8cc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was impressed that it didn't die immediately when I tried looking at the file.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd / # modprobe cls_cgroup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd / # rmmod cls_cgroup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ERROR: Module cls_cgroup is in use&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd / # rmmod -f cls_cgroup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Disabling lock debugging due to kernel taint&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd / # cd /dev&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # mkdir cgroup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;livecd dev # mount -t cgroup none -o cls_cgroup cgroup/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Modules linked in: [last unloaded: cls_cgroup]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Kernel panic - not syncing: Kernel mode fault at addr 0x0, ip 0x600fe9aa&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that this is a case that I'd eventually like to get working with module unloading (without the -f option, of course).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-573777879715475416?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/573777879715475416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/this-is-mainly-for-kernel-developers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/573777879715475416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/573777879715475416'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/11/this-is-mainly-for-kernel-developers.html' title='&quot;This is mainly for kernel developers and desperate users.&quot;'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-4880387657728242213</id><published>2009-10-26T23:47:00.005-04:00</published><updated>2009-10-27T12:17:39.162-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='gdb'/><title type='text'>what did the segmentation violation handler say to the general protection handler when the kernel panicked?</title><content type='html'>&lt;span style="font-family:courier new;"&gt;livecd / # modprobe cls_cgroup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; [New LWP 21722]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                linux-nat.c:1152: internal-error: linux_nat_resume: Assertion `lp != NULL' failed.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; A problem internal to GDB has been detected,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; further debugging may prove unreliable.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; Quit this debugging session? (y or n)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Currently merging gdb-7.0 and hoping that won't have the same bug. [edit: new version seems to work fine.]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-4880387657728242213?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/4880387657728242213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/what-did-segmentation-violation-handler.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/4880387657728242213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/4880387657728242213'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/what-did-segmentation-violation-handler.html' title='what did the segmentation violation handler say to the general protection handler when the kernel panicked?'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-4811012153019909832</id><published>2009-10-21T12:54:00.003-04:00</published><updated>2009-10-21T13:03:39.772-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='lkml'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Midsemester plan (as seen in the 412 project volume!)</title><content type='html'>&lt;span style="font-weight: bold;"&gt;milestones! \o_&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;this week:&lt;/span&gt;&lt;br /&gt;clean up my work for my other classes and get my brain back in shape! possibly even refactor some of the code that i have identified as needing refactoring. also stop being so lazy and mirror my work/source tree in the project volume.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;next week:&lt;/span&gt;&lt;br /&gt;polish up my current features - namely, the so-far-implemented subsys[] modifications, and module interface within cgroups, and the conversion of net_cls to be able to be modulificarized. possibly even submit first draft to LKML and folks, get reviews!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;week after (nov 1-7):&lt;/span&gt;&lt;br /&gt;think up how to do module unloading support; logistics of pinning the subsystems when loaded and letting them go when a hierarchy is unmounted. possibly begin implementing this thing. possibly consider any reviews gotten on LKML for first submission.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;nov 8-14:&lt;/span&gt;&lt;br /&gt;work should be moving along solidly on module unloading and/or fixing lkml reviews.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;nov 15-21:&lt;/span&gt;&lt;br /&gt;one or both of above should be finished. shoot for another submission to lkml around this time?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;nov 22-28:&lt;/span&gt;&lt;br /&gt;if not lkmled last week, module unloading should be first-draft done and thinged this week.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;nov 29-dec 5:&lt;/span&gt;&lt;br /&gt;rest of semester should be dedicated to finalizing everything and making the critics from lkml happy&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;grading criteria! _o/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;C&lt;/span&gt;: idea rejected or otherwise falls apart somehow, implementation turns out to be very shaky, didn't get any shininess done on top of the rudimentary stuff.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;B&lt;/span&gt;: implementation possibly a little shaky, the lkml dudes don't like it yet, a sizeable amount more work to be done before it can be called a real feature, not a lot of shininess. alternatively, a bare rudimentary implementation taken by lkml but with nothing shiny at all (i.e., pretty much what functionality i have now and nothing more)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A&lt;/span&gt;: implementation solid, most likely accepted to lkml by the end of semester, or if not, should be clearly on its way to that soon. at least a moderate amount of shininess, whether from module unloading or otherwise, should be present.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A++++ with a hug and a star-shaped sticker&lt;/span&gt;: shines more brilliantly than the sun, great features, accepted into kernel for sure by end of semester, works flawlessly and highly lauded by big-name developers as great development in computing. nobel peace prize possibly awarded.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-4811012153019909832?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/4811012153019909832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/midsemester-plan-as-seen-in-412-project.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/4811012153019909832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/4811012153019909832'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/midsemester-plan-as-seen-in-412-project.html' title='Midsemester plan (as seen in the 412 project volume!)'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-7791860818639971201</id><published>2009-10-16T02:44:00.004-04:00</published><updated>2009-10-27T12:18:00.210-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='gdb'/><title type='text'>wrestling dragons</title><content type='html'>so, next goal after doing a dummy subsystem is to start on the existing builtin subsystems. at least one should end up being modularized, and for others that I examine, analysis should be given on why they can't or would be difficult to be made into modules. so a quick glance over the existing subsystems turned into surprise progress when I discovered that &lt;span style="font-family:courier new;"&gt;net_cls&lt;/span&gt; (which additionally goes by &lt;span style="font-family:courier new;"&gt;cls_cgroup&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;net_cls_cgroup&lt;/span&gt;, and in all likelihood additional permutations thereof) not only is restricted to one file (&lt;span style="font-family:courier new;"&gt;devices&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;ns&lt;/span&gt; for example have miscellaneous function calls to them with &lt;span style="font-family:courier new;"&gt;ifdef&lt;/span&gt;s, in contrast), but also &lt;span style="font-style: italic;"&gt;already has &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;module_init()&lt;/span&gt;&lt;span style="font-style: italic;"&gt; et.al. declarations at the bottom&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;After a bit of hacking around with &lt;span style="font-family:courier new;"&gt;cgroup_load_subsys()&lt;/span&gt; (my new function) and the &lt;span style="font-family:courier new;"&gt;subsys_id&lt;/span&gt;, and also changing the &lt;span style="font-family:courier new;"&gt;Kconfig&lt;/span&gt; option to &lt;span style="font-family:courier new;"&gt;tristate&lt;/span&gt;, the build system happily modulificatarized &lt;span style="font-family:courier new;"&gt;net_cls&lt;/span&gt; for me. Booting up UML, I realized it was probably time to figure out how to make &lt;span style="font-family:courier new;"&gt;modprobe&lt;/span&gt; do the right thing - as it turns out, &lt;a href="http://user-mode-linux.sourceforge.net/hacking.html#Modules"&gt;UML's documentation&lt;/a&gt; is very helpful in this regard. A quick hostfs mount and depmod later, and the module loads and runs just fine. Victoly!&lt;br /&gt;&lt;br /&gt;In other news, binding GDB to UML yields some frightening results:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;0x00007f614c38b420 in nanosleep () from /lib64/libc.so.6&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(gdb) break cgroup_load_subsys&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Breakpoint 1 at 0x60051819: file kernel/cgroup.c, line 3619.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(gdb) cont&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Continuing.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Program received signal SIGSEGV, Segmentation fault.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;memcpy () at arch/um/sys-x86_64/../../x86/lib/memcpy_64.S:68&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;68              movq %r11,              0*8(%rdi)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Current language:  auto; currently asm&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(gdb) cont&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Continuing.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Program received signal SIGSEGV, Segmentation fault.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;0x00007f614c36911b in memset () from /lib64/libc.so.6&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(gdb)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Continuing.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Program received signal SIGSEGV, Segmentation fault.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;0x00007f614c36873e in memset () from /lib64/libc.so.6&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(gdb)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Continuing.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Breakpoint 1, cgroup_load_subsys (ss=0x62828fe0) at kernel/cgroup.c:3619&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;3619            if (ss-&gt;fork || ss-&gt;exit)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Current language:  auto; currently c&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(gdb)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-7791860818639971201?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/7791860818639971201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/wrestling-dragons.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7791860818639971201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7791860818639971201'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/wrestling-dragons.html' title='wrestling dragons'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-317647107603029558</id><published>2009-10-11T17:10:00.006-04:00</published><updated>2009-10-12T00:56:56.285-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='mmotm'/><title type='text'>a module loading adventure of the "great success" variety</title><content type='html'>okay! so, yesterday, and the day before that, and a little bit today, but mostly yesterday (in fact, for just about all of yesterday), I put together two patches in my stgit tree which I called &lt;span style="font-family:courier new;"&gt;cgroups-revamp-subsys-array.patch&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;cgroups-subsys-module-interface.patch&lt;/span&gt;, satisfying (in a very rudimentary way) #2 and #3 from the roadmap. (#1 turned out to be something I needed to keep but work around anyway... details not important now.) I made sure they compiled and went to bed.&lt;br /&gt;&lt;br /&gt;Today, after looking at ns_cgroup.c and devices_cgroup.c and realizing that they couldn't really be modularized easily, I threw together a &lt;a href="http://pastebin.ca/1613531"&gt;skeleton subsystem&lt;/a&gt; modeled after the other ones that adds a file "hax" that wraps a global variable whose value determines whether you can attach tasks to the cgroup or not. All right, now let's follow &lt;a href="http://www.cyberciti.biz/tips/build-linux-kernel-module-against-installed-kernel-source-tree.html"&gt;this guide&lt;/a&gt; that &lt;a href="http://amoeba.ugrad.cs.cmu.edu:15412/wiki/elly1_project/index.html"&gt;elly&lt;/a&gt; pointed me at to get it to build as a module...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;WARNING: "cgroup_load_subsys" [/home/bblum/Documents/School/F09/412/hax/cgroup_test1.ko] undefined!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;WARNING: "cgroup_add_file" [/home/bblum/Documents/School/F09/412/hax/cgroup_test1.ko] undefined!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well, they're just warnings, so try loading the module anyway, right? (Note: I use &lt;span style="font-family:courier new;"&gt;insmod&lt;/span&gt; instead of &lt;span style="font-family:courier new;"&gt;modprobe&lt;/span&gt; because the latter wants infrastructure and dependencies, and the former can just take any random file from the filesystem.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd / # mount -t hostfs none -o /home/bblum/412 /mnt/host/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd / # cd /mnt/host/hax/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd hax # insmod cgroup_test1.ko&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup_test1: Unknown symbol cgroup_load_subsys&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup_test1: Unknown symbol cgroup_add_file&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;insmod: error inserting 'cgroup_test1.ko': -1 Unknown symbol in module&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It was worth a shot, though. Turns out I need to &lt;span style="font-family:courier new;"&gt;EXPORT_SYMBOL(...)&lt;/span&gt; everything I'll need for the module in &lt;span style="font-family:courier new;"&gt;kernel/cgroup.c&lt;/span&gt;. For now, I just do the functions my subsystem uses; later, I'll need to worry about functions that -any- subsystem might use. Next:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd hax # insmod cgroup_test1.ko&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup_test1: version magic '2.6.31-rc9-mm1-gf013913 mod_unload ' should be '2.6.31-rc9-mm1-ge40e265 mod_unload '&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;insmod: error inserting 'cgroup_test1.ko': -1 Invalid module format&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It took too long to realize that the kernel I'd most recently booted somehow had something different enough to change the vermagic string from the most recent time I'd built it, which is what I'd built the module against. Okay. Rebooting UML, and going to get it right this time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd hax # insmod cgroup_test1.ko&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Kernel panic - not syncing: Kernel mode signal 4&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Modules linked in: cgroup_test1(+)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Segmentation fault&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I had deliberately left out the "&lt;span style="font-family:courier new;"&gt;.module = THIS_MODULE&lt;/span&gt;" line in &lt;span style="font-family:courier new;"&gt;test1_subsys&lt;/span&gt; &lt;span style="font-family:webdings;"&gt;&lt;/span&gt;when first building it, to see what would happen when &lt;span style="font-family:courier new;"&gt;cgroup_load_subsys&lt;/span&gt; tried to pin the module... and promptly forgotten about it. Putting the line in, finally, and:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # lsmod&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Module                  Size  Used by&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # mount -t cgroup none -o test1 cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;mount: special device none does not exist&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # insmod /mnt/host/hax/cgroup_test1.ko&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # lsmod&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Module                  Size  Used by&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup_test1            2512  1 [permanent]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # mount -t cgroup none -o test1 cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # ls cgroup/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cgroup.procs  notify_on_release  release_agent  tasks  test1.hax&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # mkdir cgroup/foo&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # echo $$ &gt; cgroup/foo/tasks&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;bash: echo: write error: Operation not permitted&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # echo 42 &gt; cgroup/foo/test1.hax&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev # echo $$ &gt; cgroup/foo/tasks&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;livecd dev #&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;:)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-317647107603029558?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/317647107603029558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/module-loading-adventure-of-great.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/317647107603029558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/317647107603029558'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/module-loading-adventure-of-great.html' title='a module loading adventure of the &quot;great success&quot; variety'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-3143232037998326855</id><published>2009-10-08T16:11:00.004-04:00</published><updated>2009-10-08T18:19:01.164-04:00</updated><title type='text'>what some people don't realize is that you can't stereotype my group as a "c" group.</title><content type='html'>because we do it all: cpuset, devices, freezer, memory. you name it, we've done it. it don't matter to me: if the cache is hot, we gonna kill it.&lt;br /&gt;&lt;br /&gt;we're here to control processes, bottom line - we have a whole lot of files from different subsystems, so we gotta make sure we keep a directory of them, ya know? directed like cgroups.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-3143232037998326855?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/3143232037998326855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/what-some-people-dont-realize-is-that.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/3143232037998326855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/3143232037998326855'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/what-some-people-dont-realize-is-that.html' title='what some people don&apos;t realize is that you can&apos;t stereotype my group as a &quot;c&quot; group.'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-8033183780927673654</id><published>2009-10-08T14:51:00.003-04:00</published><updated>2009-10-08T16:11:09.758-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='milestones'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>roadmap</title><content type='html'>all right, so it seems like a good idea to map out the ideas and targets I've got in my head, for several reasons. Here's what I've determined I should be doing.&lt;br /&gt;&lt;br /&gt;1) Fork/exit callbacks need to go. It's this functionality that cgroups has offered since (presumably) it first hit mainline in which a subsystem can set itself up to get a function called whenever a task forks or exits. Apparently, no subsystem has ever used it, and the presence of it here is going to interact funnily with module-loadable subsystems, so - at the suggestion and approval of Paul - I'm going to strip all callback code out of cgroups. This will be done as a pre-patch to the main patch series I plan on generating.&lt;br /&gt;&lt;br /&gt;2) Changing how &lt;span style="font-family: courier new;"&gt;subsys[]&lt;/span&gt; is used.&lt;br /&gt;  a) At the bottom of the array will be the entries for builtin subsystems, which will be there at link-time, up until &lt;span style="font-family: courier new;"&gt;CGROUP_BUILTIN_SUBSYS_COUNT&lt;/span&gt;. &lt;span style="font-family: courier new;"&gt;CGROUP_SUBSYS_COUNT&lt;/span&gt;, which used to be that, is now defined as the size of the &lt;span style="font-family: courier new;"&gt;subsys_bits&lt;/span&gt; field in &lt;span style="font-family: courier new;"&gt;cgroupfs_root&lt;/span&gt; (i.e., 32 or 64), and is still the max size of the array. At link time, all entries between the builtin count and the total count will be &lt;span style="font-family: courier new;"&gt;NULL&lt;/span&gt;, and that's where module subsystems will put themselves. (This is done.) Also, the array will need to be surrounded in a rwlock, since when a subsystem registers itself it will need to take a &lt;span style="font-family: courier new;"&gt;subsys_id&lt;/span&gt;. (This is not done.)&lt;br /&gt;  b) All code throughout cgroups needs to be able to handle when a subsystem is gone. Each loop that iterates down the array will need to have a check for null pointers (this is done) and take the read-lock (this is not done). There may also be other things that certain loops need to do, situationally - this is as yet unclear.&lt;br /&gt;&lt;br /&gt;3) &lt;span style="font-family: courier new;"&gt;cgroup_init_subsys()&lt;/span&gt; needs to be revised to be suitable as a module initcall. It needs to be able to handle failures correctly (the current version will kpanic on initialization fail, since it's assumed to call at boot time only). Of course, because some subsystems will be left as builtins, we'll still need a version suitable for calling at boottime - probably just a wrapper around the adapted module initcall. Also, we'll need to be concurrency-safe now - obviously around the subsys array, and possibly in the other various things that the function does. Among other things, when the module is loaded OR when the module is mounted on a cgroup hierarchy (see note at end of post) we'll need to pin it with &lt;span style="font-family: courier new;"&gt;try_module_get()&lt;/span&gt; to make sure it doesn't go away.&lt;br /&gt;&lt;br /&gt;Once we hit this point, it can be said that cgroups has support for modular subsystems. Next, we do the whole "confirming" thing:&lt;br /&gt;&lt;br /&gt;4) adapt one or more subsystems to become modules, or perhaps write a new skeleton one for testing, or both. in order to be a module (suppose your module is "foo" as &lt;span style="font-family: courier new;"&gt;CONFIG_FOO&lt;/span&gt;), you need to do the following things:&lt;br /&gt;  a) instead of having code interspersed in other code with stuff like &lt;span style="font-family: courier new;"&gt;#ifdef CONFIG_FOO&lt;/span&gt;, it has to be all in the same file (since each .o file is either going to be a builtin or a module). in the kconfig, you need to specify that it's buildable as a module, and in the makefile, you need to make sure that the config file corresponds to the right source file.&lt;br /&gt;  b) you need to register a bunch of stuff with the &lt;span style="font-family: courier new;"&gt;module_suchandsuch()&lt;/span&gt; macros - like name, version, author, and most importantly &lt;span style="font-family: courier new;"&gt;module_init()&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;module_exit()&lt;/span&gt;, which define what functions are called at module load and unload time. (the infrastructure behind this and these macros is a lot of hax.)&lt;br /&gt;&lt;br /&gt;I am uncertain whether I'll end up supporting module unloading for cgroups - it seems like it would be useful, given that we have a limit on the number of subsystems loaded at a time. I think this would involve making sure that subsystems can't be unloaded while attached to any mounted hierarchy, but can when not. This likely will necessitate use of &lt;span style="font-family: courier new;"&gt;cgroup_lock&lt;/span&gt;. If we do this, we'll end up pinning the module when we mount a hierarchy - there will be a race here if somebody's trying to unload the module at the same time, so when mounting, pinning all subsystems will have to be done before committing to the mount.&lt;br /&gt;&lt;br /&gt;The alternative approach - and the one that I'll go with to begin with, for sure - is to just say nope, never unload, and the module is pinned forever as soon as it's loaded.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-8033183780927673654?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/8033183780927673654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/roadmap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/8033183780927673654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/8033183780927673654'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/roadmap.html' title='roadmap'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-6758582711615044297</id><published>2009-10-06T17:03:00.004-04:00</published><updated>2009-10-06T20:09:10.900-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='mmotm'/><title type='text'>understanding is powered by magic</title><content type='html'>I spent a good hour or two this afternoon poring over the kernel's module build infrastructure (not daring to look at any .c files, of course), looking at various other module code trying to take them as examples. Something clicked in my head then while looking at &lt;span style="font-family:courier new;"&gt;include/linux/init.h&lt;/span&gt;, which hadn't done before, presumably because I hadn't looked at module examples, and suddenly I understood how things wanted to be compiled as modules and have initcalls/exitcalls registered.&lt;br /&gt;&lt;br /&gt;It seems (read: I've been advised) that each subsystem will want to have a pointer to its &lt;span style="font-family:courier new;"&gt;struct module&lt;/span&gt;, so it can keep it "pinned" while the subsystem is loaded. This raises an interesting question: where the hell does the module struct come from? &lt;span style="font-family:courier new;"&gt;include/linux/module.h&lt;/span&gt; has a macro called &lt;span style="font-family:courier new;"&gt;THIS_MODULE&lt;/span&gt; which references &lt;span style="font-family:courier new;"&gt;extern struct module __this_module&lt;/span&gt;. Looking at a few examples, some of them have &lt;span style="font-family:courier new;"&gt;foo.mod.c&lt;/span&gt; files, which all look to have the same struct declaration (with perhaps a few differences, namely in the &lt;span style="font-family:courier new;"&gt;"depends="&lt;/span&gt; string at the end). However, modules that I found living in &lt;span style="font-family:courier new;"&gt;kernel/&lt;/span&gt; don't tend to have that, though everything else (use of the &lt;span style="font-family:courier new;"&gt;initcall&lt;/span&gt; macros, etc) was the same. Where does this mystery struct come from? A grep through the standard directories revealed nothing; grepping the whole source tree discovered the file &lt;span style="font-family:courier new;"&gt;scripts/mod/modpost.c&lt;/span&gt; which... generates a header file for module code with the relevant struct information. As in, "&lt;span style="font-family: courier new;"&gt;buf_printf(b, "struct module __this_module\n");&lt;/span&gt;" with surrounding context. Ugh.&lt;br /&gt;&lt;br /&gt;I need to learn to start trusting the macros (&lt;span style="font-family:courier new;"&gt;THIS_MODULE&lt;/span&gt;, in this case) that look like complete hax instead of trying to figure out what the hax are.&lt;br /&gt;&lt;br /&gt;As a note to myself, the CONFIG_CGROUP option settings live in init/Kconfig, and to enable modularization on an option you need to change 'bool' to 'tristate'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-6758582711615044297?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/6758582711615044297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/understanding-is-powered-by-magic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/6758582711615044297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/6758582711615044297'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/understanding-is-powered-by-magic.html' title='understanding is powered by magic'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-4620775915526487984</id><published>2009-10-03T01:44:00.002-04:00</published><updated>2009-10-03T01:58:18.470-04:00</updated><title type='text'>gaining momentum</title><content type='html'>I spent some time today looking through kernel/cgroup.c (and a bit of cgroup.h), focusing on the uses of the subsys[] array - the one that's currently initialized and link-time and will need to be redone for dynamic loading - and thinking about how to change it.&lt;br /&gt;&lt;br /&gt;For one thing, cgroup_init_subsys() will need to no longer be marked as __init, and will need to be concurrency-safe (against itself, too). I think that no matter what data structure I end up using for the subsystem list, it will be guarded by a rwlock (or rwsem. one is a low-level lock, the other isn't). Aside from that, the only other challenge there appears to be the fork/exit callbacks logic, which I think can be for the most part disregarded - or thought about very briefly at least - since currently no subsystem even uses the callbacks.&lt;br /&gt;&lt;br /&gt;As for the subsys[] array, the question of how to make it support new guys appearing is a difficult one. At first I thought I could make it a list, with list_head structs in each subsystem's struct - which might still be possible... but looking through all the uses of it, there will prove to be some fiddly bits. Namely, there are other data structures that rely on the list of subsystems being a fixed-length array - cgroup-&gt;subsys[] and css_set-&gt;subsys[], which is a list of cgroup_subsys_state objects (good naming there, guys), and also the use of template[] in find_existing_css_set (which I used over the summer!) all rely on matching up with the global subsys[] array. Additionally, struct cgroupfs_root has a pair of fields (unsigned long) called subsys_bits and actual_subsys_bits, which keep track of which subsystems are or want to be attached. So, thoughts for this are either:&lt;br /&gt;&lt;br /&gt;1. figure out some way to do a dynamic list for subsys[] and its corresponding things, which will involve possibly fiddly uses of kmalloc() (with accompanying fail cases) and/or relying on cgroup_mutex and throwing another list_head in the subsys structs somewhere. also, replacing subsys_bits with something more suitable.&lt;br /&gt;2. simply set CGROUP_SUBSYS_COUNT to sizeof(subsys_bits)*8 (i.e., maximum number of subsystems at a time is the number of bits in the thing field) and let the array have null slots in it. this seems a lot easier, but is avoiding the design problem. on the other hand, they designed clone_flags to have 32 possible settings, and they ran out of those recently, so...&lt;br /&gt;&lt;br /&gt;I hope to spend a good chunk of tomorrow coding.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-4620775915526487984?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/4620775915526487984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/gaining-momentum.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/4620775915526487984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/4620775915526487984'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/10/gaining-momentum.html' title='gaining momentum'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-6216354730303492185</id><published>2009-09-21T01:46:00.004-04:00</published><updated>2009-09-21T01:55:54.731-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>last-minute presentation slides!</title><content type='html'>My project presentation in 412 is in eleven hours, and I've just finished and test-presented my slides. Here they are, for reference:&lt;br /&gt;&lt;br /&gt;http://maximegalon.res.cmu.edu/home/bblum/project.pdf&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-6216354730303492185?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/6216354730303492185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/09/last-minute-presentation-slides.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/6216354730303492185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/6216354730303492185'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/09/last-minute-presentation-slides.html' title='last-minute presentation slides!'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-7695067093499804898</id><published>2009-09-13T20:17:00.003-04:00</published><updated>2009-09-13T20:43:41.466-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='mmotm'/><title type='text'>UML</title><content type='html'>I spent a good portion of today (and small amounts of time previously) trying to get a good environment for this set up. This mostly involved getting the mm-of-the-moment (mmotm) tree and making UML (user-mode linux, the way i will test most of the stuff) actually go properly.&lt;br /&gt;&lt;br /&gt;choosing an environment:&lt;br /&gt;magrathea (my laptop): runs 64-bit. last time i tried gitting mmotm and building the kernel, it failed. :iiam:&lt;br /&gt;maximegalon (my server): runs 32-bit. comparatively slow processor, so build times suboptimal.&lt;br /&gt;unix.andrew servers: AFS volume only 1GB, mmotm tree with built objects in it is larger. I was given the suggestion to ask for a project volume, but :effort:&lt;br /&gt;&lt;br /&gt;I eventually discovered that the build failure on magrathea was bash's fault. Version 4 strips environment variables with a "." in the name, and the kernel's makefiles depend on not-that-behaviour. During my googling that determined this, I found a mailing list discussing design implications and whether or not bash-4 should actually do that anyway or not. Magrathea now has bash-3 installed, and the kernel builds nicely.&lt;br /&gt;&lt;br /&gt;The next thing I needed to do was obtain a filesystem to run UML on. I at first tried just laying it on top of my laptop's root filesystem (with &lt;span style="font-family:courier new;"&gt;./linux root=/dev/root rootfstype=hostfs rootflags=/ rw&lt;/span&gt;), but my current gentoo installation's boot sequence is fancy enough that UML complained on a lot of the steps. Also, running as user forbids it from writing to anything that it needs to be able to write to, and furthermore found permissions conflicts with &lt;span style="font-family:courier new;"&gt;/bin/mount&lt;/span&gt;, which I sort of need a lot for cgroups devel.&lt;br /&gt;&lt;br /&gt;Next I tried pulling a debian root filesystem from maximegalon, and running with that. That gave me the mystery "&lt;span style="font-family:courier new;"&gt;request_module: runaway loop modprobe binfmt-464c&lt;/span&gt;" (several times in a row, then hangs) immediately after mounting the root fs. I didn't examine it and instead looked for an alternative approach, finding &lt;span style="font-family:courier new;"&gt;rootstrap&lt;/span&gt;,  a script designed to automatically build a UML root fs from scratch. It failed instantly complaining about &lt;span style="font-family:courier new;"&gt;mount&lt;/span&gt;'s permissions (same as booting with my laptop's root). I next pulled down a prebuilt slackware root fs from UML's website - same &lt;span style="font-family:courier new;"&gt;binfmt-464c&lt;/span&gt; error. This time I googled it and discovered that that's what happens when you feed a 64-bit kernel (UML doesn't seem to have &lt;span style="font-family:courier new;"&gt;CONFIG_IA32_EMULATION&lt;/span&gt; for some reason?) a 32-bit filesystem.&lt;br /&gt;&lt;br /&gt;With newfound resolve, I pulled down the amd64 minimal install CD ISO from Gentoo's website, loopback-mounted it, found the squashfs image therein, discovered my host kernel didn't have squashfs, built it as a module, then mounted the root filesystem and booted it. Same problem with &lt;span style="font-family:courier new;"&gt;/bin/mount&lt;/span&gt; as before. Okay, well, I'll change the permissions on this one since it's not on a filesystem I care about. At least, I would have done that, if the loopback-mounted squashfs image within the loopback-mounted ISO could at all be made not readonly. Instead I made myself a new filesystem (&lt;span style="font-family:courier new;"&gt;dd if=/dev/zero of=/tmp/uml_root bs=1024 count=1 seek=$((1024*1024-1)); /sbin/mke2fs -j /tmp/uml_root&lt;/span&gt;)  and copied it over. That seemed to boot fine, until I got to the end, when after "&lt;span style="font-family:courier new;"&gt;Starting local ... [ ok ]&lt;/span&gt;" (the last message in the boot sequence before &lt;span style="font-family:courier new;"&gt;agetty&lt;/span&gt; runs, it printed a lot of "&lt;span style="font-family:courier new;"&gt;IRQF_DISABLED is not guaranteed on shared IRQs&lt;/span&gt;" messages and hung (and spawned a lot of xterms on the host kernel, too. wtf?). Google revealed no useful information, so I figured that as this was the homestretch a bit of hackery was allowed: I opened up &lt;span style="font-family:courier new;"&gt;/etc/conf.d/local.start&lt;/span&gt; and appended &lt;span style="font-family:courier new;"&gt;exec /bin/bash&lt;/span&gt;. Now when it booted up, it ended with a root shell.&lt;br /&gt;&lt;br /&gt;Just to make sure everything was in working order - i.e., appropriate for doing devel with - I went to go mount cgroups (&lt;span style="font-family:courier new;"&gt;mkdir /dev/cgroups; mount -t cgroup none /dev/cgroup&lt;/span&gt;) and have a look. There I see the standard cgroups and subsystem control files, and also something I didn't expect to see: &lt;span style="font-family:courier new;"&gt;/dev/cgroup/cgroup.procs&lt;/span&gt;. That's the file that the patchseries I put together over the summer implemented, submitted to LKML a couple of times, and had somewhat lost track of as Paul (google mentor) had taken over its custody when I left. Looks like it got into the tree after all - I'm taking that as a sign of hope for this project :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-7695067093499804898?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/7695067093499804898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/09/uml.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7695067093499804898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/7695067093499804898'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/09/uml.html' title='UML'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1014297917047073169.post-8767016101945424853</id><published>2009-09-13T19:22:00.001-04:00</published><updated>2009-09-21T01:56:12.983-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><category scheme='http://www.blogger.com/atom/ns#' term='proposal'/><title type='text'>welcome to my 412 project's blog: project proposal [repost]</title><content type='html'>following is the preliminary (read: rough) project proposal I submitted a week or two ago, as per &lt;a href="http://www.cs.cmu.edu/%7E412/projects.html#proposals"&gt;this guide&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PROJECT PROPOSAL - Linux CGroups: Subsystems as Modules&lt;/span&gt;&lt;br /&gt;http://lkml.org&lt;br /&gt;http://www.mjmwired.net/kernel/Documentation/cgroups.txt&lt;br /&gt;&lt;br /&gt;This project aims to alter the cgroups infrastructure to support subsystems as kernel modules. cgroups will need to be enhanced to deal with subsystems that are "not there", and for each subsysem some consideration will need to be done on the implications of it being dynamically loaded. This will entail a wide and thorough, but not deep and intricate, development on the core cgroups code, and changes on subsystems possibly ranging from superficial to major depending on the particular nature.&lt;br /&gt;&lt;br /&gt;The control groups mechanism in Linux is currently implemented as a core part of the kernel, mostly in kernel/cgroup.c, with various peripheral code (mostly subsystem-wise) scattered throughout a few other files (sched.c, ns_cgroup.c, memcontrol.c, etcetera). As it is a rather high-level part of the kernel, all of it is in C, and the development process is standard linux kernel devel, complete with LKML submissions at the end (read: surprise, more work to do).&lt;br /&gt;&lt;br /&gt;As this project is enabling module functionality for subsystems, the task will begin with energy being dedicated to understanding the modules system within linux. At about the same time, an interface with which to see the modules will have to be developed, and only after knowing what's going on will modulifying begin (naturally).&lt;br /&gt;&lt;br /&gt;As far as linux development goes, cgroups seems to be fairly relatively slow. A patch series from my work over the summer is currently being landed, and may cause excitement with this project if it takes too long. Other than that, clashes should be minor enough.&lt;br /&gt;&lt;br /&gt;Development will be done in the mmotm ("mm of the moment") tree, using stgit on top of git. Testing can be done in both UML, for convenience, and on real hardware, for completeness. I'll likely enough collaborate with Paul Menage (mentor at google, responsible for most cgroups stuff) for guidance. Hopefully submissions to LKML will start a good way through the semester, and revisions and refinery will be done by the end.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1014297917047073169-8767016101945424853?l=cgrouphacking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cgrouphacking.blogspot.com/feeds/8767016101945424853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cgrouphacking.blogspot.com/2009/09/welcome-to-my-412-projects-blog-project.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/8767016101945424853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1014297917047073169/posts/default/8767016101945424853'/><link rel='alternate' type='text/html' href='http://cgrouphacking.blogspot.com/2009/09/welcome-to-my-412-projects-blog-project.html' title='welcome to my 412 project&apos;s blog: project proposal [repost]'/><author><name>bblum</name><uri>http://www.blogger.com/profile/18306453438355961936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
