On Mon, Apr 9, 2012 at 2:38 AM, Anton Vorontsov <anton.vorontsov@xxxxxxxxxx> wrote: > This patch implements a new event type, it will trigger whenever a > value crosses a user-specified threshold. It works two-way, i.e. when > a value crosses the threshold from a lesser values side to a greater > values side, and vice versa. > > We use the event type in an userspace low-memory killer: we get a > notification when memory becomes low, so we start freeing memory by > killing unneeded processes, and we get notification when memory hits > the threshold from another side, so we know that we freed enough of > memory. > > Signed-off-by: Anton Vorontsov <anton.vorontsov@xxxxxxxxxx> > --- > include/linux/vmevent.h | 9 +++++++++ > mm/vmevent.c | 21 +++++++++++++++++++++ > tools/testing/vmevent/vmevent-test.c | 15 ++++++++++----- > 3 files changed, 40 insertions(+), 5 deletions(-) > > diff --git a/include/linux/vmevent.h b/include/linux/vmevent.h > index 64357e4..00cc04f 100644 > --- a/include/linux/vmevent.h > +++ b/include/linux/vmevent.h > @@ -22,6 +22,15 @@ enum { > * Sample value is less than user-specified value > */ > VMEVENT_ATTR_STATE_VALUE_LT = (1UL << 0), > + /* > + * Sample value crossed user-specified value > + */ > + VMEVENT_ATTR_STATE_VALUE_CROSS = (1UL << 2), > + > + /* Last saved state, used internally by the kernel. */ > + __VMEVENT_ATTR_STATE_LAST = (1UL << 30), > + /* Not first sample, used internally by the kernel. */ > + __VMEVENT_ATTR_STATE_NFIRST = (1UL << 31), > }; > > struct vmevent_attr { > diff --git a/mm/vmevent.c b/mm/vmevent.c > index a56174f..f8fd2d6 100644 > --- a/mm/vmevent.c > +++ b/mm/vmevent.c > @@ -1,5 +1,6 @@ > #include <linux/anon_inodes.h> > #include <linux/atomic.h> > +#include <linux/compiler.h> > #include <linux/vmevent.h> > #include <linux/syscalls.h> > #include <linux/timer.h> > @@ -94,6 +95,26 @@ static bool vmevent_match(struct vmevent_watch *watch) > if (attr->state & VMEVENT_ATTR_STATE_VALUE_LT) { > if (value < attr->value) > return true; > + } else if (attr->state & VMEVENT_ATTR_STATE_VALUE_CROSS) { > + bool fst = !(attr->state & __VMEVENT_ATTR_STATE_NFIRST); > + bool old = attr->state & __VMEVENT_ATTR_STATE_LAST; > + bool new = value < attr->value; > + bool chg = old ^ new; > + bool ret = chg; > + > + /* > + * This is not 'lt' or 'gt' match, so on the first > + * sample assume we crossed the threshold. > + */ > + if (unlikely(fst)) { > + attr->state |= __VMEVENT_ATTR_STATE_NFIRST; > + ret = true; > + } > + > + attr->state &= ~__VMEVENT_ATTR_STATE_LAST; > + attr->state |= new ? __VMEVENT_ATTR_STATE_LAST : 0; > + > + return ret; > } > } > Can't we implement this by specifying both VMEVENT_ATTR_STATE_VALUE_LT and VMEVENT_ATTR_STATE_VALUE_GT in userspace? I assume the problem with current approach is that you get more than one notifications, right? We can implement a "single-shot" flag to deal with that. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href