super皮波 发表于 2015-01-20 15:21

__alloc_pages_nodemask内存分配函数有地方不理解

struct page *
__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
                        struct zonelist *zonelist, nodemask_t *nodemask)
{
        enum zone_type high_zoneidx = gfp_zone(gfp_mask);
        struct zone *preferred_zone;
        struct page *page = NULL;
        int migratetype = allocflags_to_migratetype(gfp_mask);
        unsigned int cpuset_mems_cookie;
        int alloc_flags = ALLOC_WMARK_LOW|ALLOC_CPUSET;
        struct mem_cgroup *memcg = NULL;

        gfp_mask &= gfp_allowed_mask;

        lockdep_trace_alloc(gfp_mask);

        might_sleep_if(gfp_mask & __GFP_WAIT);

        if (should_fail_alloc_page(gfp_mask, order))
                return NULL;

        /*
       * Check the zones suitable for the gfp_mask contain at least one
       * valid zone. It's possible to have an empty zonelist as a result
       * of GFP_THISNODE and a memoryless node
       */
        if (unlikely(!zonelist->_zonerefs->zone))
                return NULL;

        /*
       * Will only have any effect when __GFP_KMEMCG is set.This is
       * verified in the (always inline) callee
       */
        if (!memcg_kmem_newpage_charge(gfp_mask, &memcg, order))
                return NULL;

retry_cpuset:
        cpuset_mems_cookie = get_mems_allowed();

        /* The preferred zone is used for statistics later */
        first_zones_zonelist(zonelist, high_zoneidx,
                                nodemask ? : &cpuset_current_mems_allowed,
                                &preferred_zone);
        if (!preferred_zone)
                goto out;

我的理解:标红的地方是根据gfp标志找到优先的zone区间,而first_zones_zonelist函数的定义如下
static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist,
                                        enum zone_type highest_zoneidx,
                                        nodemask_t *nodes,
                                        struct zone **zone)
{
        return next_zones_zonelist(zonelist->_zonerefs, highest_zoneidx, nodes,
                                                                zone);
}

struct zoneref *next_zones_zonelist(struct zoneref *z,
                                        enum zone_type highest_zoneidx,
                                        nodemask_t *nodes,
                                        struct zone **zone)
{
        /*
       * Find the next suitable zone to use for the allocation.
       * Only filter based on nodemask if it's set
       */
        if (likely(nodes == NULL))
                while (zonelist_zone_idx(z) > highest_zoneidx)
                        z++;/*为什么是这个判断条件,这样的判断条件岂不是先去查看dma区了,dma分区的zone_idx是0,最小的*/
        else
                while (zonelist_zone_idx(z) > highest_zoneidx ||
                                (z->zone && !zref_in_nodemask(z, nodes)))
                        z++;

        *zone = zonelist_zone(z);
        return z;
}

不知道表达没表达清楚,帮忙看一下,谢谢

humjb_1983 发表于 2015-01-21 11:38

直到zonelist_zone_idx(z) == highest_zoneidx时,才算找到对应的zone吧,看起来好像没啥问题~,还是我没理解你的意思?呵呵

super皮波 发表于 2015-01-21 13:47

回复 2# humjb_1983

zonelist_zone_idx(z) > highest_zoneidx 这个是判断条件
dmazone的idx是最小的,所以while不成立,直接返回了
   

humjb_1983 发表于 2015-01-21 16:46

super皮波 发表于 2015-01-21 13:47 static/image/common/back.gif
回复 2# humjb_1983

zonelist_zone_idx(z) > highest_zoneidx 这个是判断条件


因为zone_type和_zonerefs中的索引是反的~~
static int build_zonelists_node(pg_data_t *pgdat, struct zonelist *zonelist,
                                int nr_zones, enum zone_type zone_type)
{
        struct zone *zone;

        BUG_ON(zone_type >= MAX_NR_ZONES);
        zone_type++;

        do {
                zone_type--;
                zone = pgdat->node_zones + zone_type;
                if (populated_zone(zone)) {
                        zoneref_set_zone(zone,
                                &zonelist->_zonerefs);
                        check_highest_zone(zone_type);
                }

        } while (zone_type);
        return nr_zones;
}
页: [1]
查看完整版本: __alloc_pages_nodemask内存分配函数有地方不理解