Re: Minimalistic consistency model (one step above null model)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 13, 2014 at 11:22:10PM -0600, Josh Poimboeuf wrote:

> > The really trivial solution is:
> > 
> > 
> > 	static void lpc_ftrace_handler(unsigned long ip, unsigned long parent_ip,
> > 					struct ftrace_ops *ops, struct pt_regs *regs)
> > 	{
> > 		struct lpc_func *func = ops->private;
> > 
> > 		if (!within_patched_set(parent_ip))
> > 			regs->ip = func->new_addr;
> > 	}
> > 
> > 
> > Obviously, within_patched_set() would need an efficient data structure,
> > like an interval tree, to quickly decide whether the parent ip address
> > is within the patched set.
> > 
> > This is enough to make sure that function calls are consistent.
> > 
> > No stack checking, no stop_machine(), no forcing threads through
> > userspace.
> > 
> > A disadvantage is that it doesn't give an indication when patching is
> > over and the trampoline can be removed. For that, I currently don't see
> > a better method than tracking kernel exits and/or stack analysis.
> > 
> > What do you think?
> 
> Interesting idea.  But the hard part is figuring out when the patching
> is complete.  Once you implement that, it might not be so minimal.

True.

The same applies to the current livepatch implementation, though.  You
cannot tell if all threads have left the functions you've patched or
whether they're remaining on the stack and as such cannot remove patches
safely nor start transforming data.

The above implementation of extending the current livepatch to handle
function prototype changes can be further extended to handle multiple
patches 'in progress' by only jumping to a 'next level' patch if coming
from a function not changed by that level.


> BTW, here's a very simple way to implement LEAVE_PATCHED_SET +
> SWITCH_THREAD:
> 
> for each thread {
>     if (!on_cpu(thread) and !on_stack(thread, funcs) {
>         switch thread to new universe
>     } else if (unfreezable kthread) {
>         retry and/or fail (kthread is either CPU-bound or is using patched func)
>     } else {
>         freeze thread
> 	if (!on_stack(thread, funcs))
> 	    switch thread to new universe
> 	else
> 	    fail (patch affects freezer/schedule path)
>     }
> }

I think this could work. You need to make sure you can prevent a process
from waking up, however, to avoid race conditions in the first if().

A very similar method could be used to detect if the minimalistic
approach above finished patching, trampolines can be removed, data
patching started, etc.

> Note this approach will fail in a few cases, like if you have a
> CPU-bound kthread (but we can keep retrying in that case), if a patched
> function is in use by a sleeping kthread, or if the patch affects the
> freeze/schedule path.

None of the so far proposed methods can complete patching if a patched
function is in use by a sleeping kthread, or even any thread. So the
limitations you show aren't a huge problem.

> But the code is simple and converges to the patched state quickly.
> 
> Thoughts?

You could avoid the freezing (and thus userspace impact) by tracking
syscall (or freezer) entry/exit like kGraft does. Any process cpu-bound
in userspace can be migrated immediately and any proces executing
syscalls can be migrated when on the kernel/userspace boundary. And
processes that are sleeping are already handled.

-- 
Vojtech Pavlik
Director SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe live-patching" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux