lkml.org 
[lkml]   [2012]   [Feb]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    SubjectRe: [PATCH 2/2] [RFC] fadvise: Add _VOLATILE,_ISVOLATILE, and _NONVOLATILE flags
    From
    On 10 February 2012 01:16, John Stultz <john.stultz@linaro.org> wrote:

    [ ... ]

    > +/*
    > + * Mark a region as nonvolatile, returns 1 if any pages in the region
    > + * were purged.
    > + */
    > +long mapping_range_nonvolatile(struct address_space *mapping,
    > +                               pgoff_t start_index, pgoff_t end_index)
    > +{
    > +       struct volatile_range *new;
    > +       struct range_tree_node *node;
    > +       int ret  = 0;
    > +       u64 start, end;
    > +       start = (u64)start_index;
    > +       end = (u64)end_index;
    > +
    > +       mutex_lock(&mapping->vlist_mutex);
    > +       node = range_tree_in_range(mapping->volatile_root, start, end);
    > +       while (node) {
    > +               struct volatile_range *vrange;
    > +               vrange = container_of(node, struct volatile_range, range_node);
    > +
    > +               ret |= vrange->purged;

    again, racing with volatile_shrink() here, so we can return a stale state.

    > +
    > +               if (start <= node->start && end >= node->end) {
    > +                       vrange_del(vrange);
    > +               } else if (node->start >= start) {
    > +                       volatile_range_shrink(vrange, end+1, node->end);
    > +               } else if (node->end <= end) {
    > +                       volatile_range_shrink(vrange, node->start, start-1);
    > +               } else {
    > +                       /* create new node */
    > +                       new = vrange_alloc(); /* XXX ENOMEM HERE? */
    > +
    > +                       new->mapping = mapping;
    > +                       new->range_node.start = end + 1;
    > +                       new->range_node.end = node->end;

    new->purged = vrange->purged ?

    > +                       volatile_range_shrink(vrange, node->start, start-1);
    > +                       mapping->volatile_root =
    > +                               range_tree_add(mapping->volatile_root,
    > +                                               &new->range_node);
    > +                       if (range_on_lru(new))
    > +                               lru_add(new);
    > +                       break;
    > +               }
    > +               node = range_tree_in_range(mapping->volatile_root, start, end);
    > +       }
    > +       mutex_unlock(&mapping->vlist_mutex);
    > +
    > +       return ret;
    > +}
    > +

    Also, I have a question about mapping_range_volatile().

    +long mapping_range_volatile(struct address_space *mapping,
    + pgoff_t start_index, pgoff_t end_index)
    +{
    + struct volatile_range *new;
    + struct range_tree_node *node;
    +
    + u64 start, end;
    + int purged = 0;
    + start = (u64)start_index;
    + end = (u64)end_index;
    +
    + new = vrange_alloc();
    + if (!new)
    + return -ENOMEM;
    +
    + mutex_lock(&mapping->vlist_mutex);
    +
    + node = range_tree_in_range_adjacent(mapping->volatile_root, start, end);
    + while (node) {
    + struct volatile_range *vrange;
    +
    + /* Already entirely marked volatile, so we're done */
    + if (node->start < start && node->end > end) {
    + /* don't need the allocated value */
    + kfree(new);
    + return 0;
    + }
    +
    + /* Grab containing volatile range */
    + vrange = container_of(node, struct volatile_range, range_node);
    +
    + /* resize range */
    + start = min_t(u64, start, node->start);
    + end = max_t(u64, end, node->end);
    + purged |= vrange->purged;
    +
    + vrange_del(vrange);
    +
    + /* get the next possible overlap */
    + node = range_tree_in_range(mapping->volatile_root, start, end);
    + }
    +
    + new->mapping = mapping;
    + new->range_node.start = start;
    + new->range_node.end = end;
    + new->purged = purged;

    I'm wondering whether this 'inheritance' is always desirable.

    Say,

    mapping_range_volatile(mapping, X, X + 1);
    ...
    time goes by and volatile_shrink() has been called for this region.

    now, a user does the following (is it considered bad user-behavior?)

    mapping_range_volatile(mapping, Y = X - big_value, Z = X + big_value);

    This new range will 'inherit' purged=1 from the old one and won't be
    on the lru_list. Yet, it's much bigger than the old one and so many
    pages are not really 'volatile'.


    -- Dmitry
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2012-02-12 15:11    [W:0.030 / U:30.628 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site