linux cgroup代碼學習(2)——數據結構整理

相關的結構

  • task_struct

定義了CONFIG_CGROUPS宏的話,task_struct和cgroup相關的變量有:css

/* Control Group info protected by css_set_lock */
    struct css_set __rcu *cgroups;//關聯的css_set
    /* cg_list protected by css_set_lock and tsk->alloc_lock */
    struct list_head cg_list;//加入css_set中tasks鏈表,全部css_set相同的鏈表。
  • CSS_SET
struct css_set {

    /* Reference count */
    atomic_t refcount;//引用計數

    /*
     * List running through all cgroup groups in the same hash
     * slot. Protected by css_set_lock
     */
    struct hlist_node hlist;//具備hash的css_set 鏈表.

    /*
     * List running through all tasks using this cgroup
     * group. Protected by css_set_lock
     */
    struct list_head tasks;//全部具備相同css_set的task_struct鏈表。

    /*
     * List of cg_cgroup_link objects on link chains from
     * cgroups referenced from this css_set. Protected by
     * css_set_lock
     */
    struct list_head cg_links;//由cg_cgroup_link組成的鏈表,鏈表上每一項cg_cgroup_link都指向和css_set關聯的cgroup.

    /*
     * Set of subsystem states, one for each subsystem. This array
     * is immutable after creation apart from the init_css_set
     * during subsystem registration (at boot time) and modular subsystem
     * loading/unloading.
     */
    /*
     *css_set關聯的css.每個subsystem對應數組中相應id的項。
     *subsys應當包括全部子系統的css.若是此css_set沒有制定某個subsystem的css或者subsystem沒有mount,則默認初始化爲根css.
     */
    struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];

    /* For RCU-protected deletion */
    struct rcu_head rcu_head;
    }

css_set是直接和task關聯的結構,css_set用來關聯一組cgroup_subsys_state對象,同時經過cg_cgroup_link和全部相關的cgroup創建關聯。node

  • cgroup
struct cgroup {
    unsigned long flags;        /* "unsigned long" so bitops work */

    /*
     * count users of this cgroup. >0 means busy, but doesn't
     * necessarily indicate the number of tasks in the cgroup
     */
    atomic_t count;//cgroup引用計數

    int id;                /* ida allocated in-hierarchy ID */

    /*
     * We link our 'sibling' struct into our parent's 'children'.
     * Our children link their 'sibling' into our 'children'.
     */
    struct list_head sibling;    /* my parent's children */ //兄弟cgroup
    struct list_head children;    /* my children */ //child cgroups
    struct list_head files;        /* my files */

    struct cgroup *parent;        /* my parent */   //parent cgroup
    struct dentry *dentry;        /* cgroup fs entry, RCU protected */ //此cgroup對應的dentry

    /*
     * This is a copy of dentry->d_name, and it's needed because
     * we can't use dentry->d_name in cgroup_path().
     *
     * You must acquire rcu_read_lock() to access cgrp->name, and
     * the only place that can change it is rename(), which is
     * protected by parent dir's i_mutex.
     *
     * Normally you should use cgroup_name() wrapper rather than
     * access it directly.
     */
    struct cgroup_name __rcu *name; //cgroup的name,同dentry->d_name

    /* Private pointers for each registered subsystem */
    struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];//此cgroup關聯subsystem的css結構,每一個subsystem的css在數組中對應subsys[subsystem->subsys_id].

    struct cgroupfs_root *root;//cgroup所處的cgroupfs_root,對應hirerarchy    
    /*
     * List of cg_cgroup_links pointing at css_sets with
     * tasks in this cgroup. Protected by css_set_lock
     */
    struct list_head css_sets; //經過cs_cgroup_link指向此cgroup關聯的css_set

    struct list_head allcg_node;    /* cgroupfs_root->allcg_list */
    struct list_head cft_q_node;    /* used during cftype add/rm */

    /*
     * Linked list running through all cgroups that can
     * potentially be reaped by the release agent. Protected by
     * release_list_lock
     */
    struct list_head release_list;

    /*
     * list of pidlists, up to two for each namespace (one for procs, one
     * for tasks); created on demand.
     */
    struct list_head pidlists;
    struct mutex pidlist_mutex;

    /* For RCU-protected deletion */
    struct rcu_head rcu_head;
    struct work_struct free_work;

    /* List of events which userspace want to receive */
    struct list_head event_list;
    spinlock_t event_list_lock;

    /* directory xattrs */
    struct simple_xattrs xattrs;
};

cgroup對應一個controll實例,須要和css_set關聯,這樣每一個task_struct就能夠經過task_struct->cgroups 繼而和cgroup關聯,達到控制和隔離資源的目的,那麼css_set和cgroup具體是怎麼關聯的呢?
首先須要明確的是cgroup和css_set是多對多的關係,既:一個css_set能夠對應多個cgroup,同時一個cgroup也能夠被多個css_set所包含。
這種多對多的映射關係,是經過cg_cgroup_link這個中間結構來關聯的。數組

/* Link structure for associating css_set objects with cgroups */
struct cg_cgroup_link {
    /*
     * List running through cg_cgroup_links associated with a
     * cgroup, anchored on cgroup->css_sets
     */
    struct list_head cgrp_link_list;
    struct cgroup *cgrp;
    /*
     * List running through cg_cgroup_links pointing at a
     * single css_set object, anchored on css_set->cg_links
     */
    struct list_head cg_link_list;
    struct css_set *cg;
};

一個cg_cgroup_link須要包含兩類信息,即關聯的cgroup和css_set信息,一個cg_cgroup_link可讓一個cgroup和一個css_set相關聯。可是正如咱們前面所說,css_set和cgroup是多對多的對應關係,因此,一個css_set須要保存多個cg_cgroup_link,一個cgroup也須要保存多個cg_cgroup_link信息。具體來講,css_set中的cg_links維護了一個鏈表,鏈表中的元素爲cg_cgroup_link中的cg_link_list.cgroup中的css_set也維護了一個cg_cgroup_link鏈表,鏈表中元素爲cgrp_link_list.結構以下圖所示:app

圖片描述

  • cgroupfs_root

cgroup_root對應一個層級,從Linux 文件系統角度來說,cgroupfs_root對應咱們mount相應cgroup時建立的super_block.即,咱們每進行一次mount操做,就對應一個cgroupfs_root的建立。函數

/*
 * A cgroupfs_root represents the root of a cgroup hierarchy, and may be
 * associated with a superblock to form an active hierarchy.  This is
 * internal to cgroup core.  Don't access directly from controllers.
 */
struct cgroupfs_root {
    //cgroupfs_root對應的super block
    struct super_block *sb;

    /*
     * The bitmask of subsystems intended to be attached to this
     * hierarchy
     */
    unsigned long subsys_mask;//此hierarchy層級中包含的子系統,以掩碼錶示

    /* Unique id for this hierarchy. */
    int hierarchy_id;//id

    /* The bitmask of subsystems currently attached to this hierarchy */
    unsigned long actual_subsys_mask;//TOBE DONE

    /* A list running through the attached subsystems */
    struct list_head subsys_list;//關聯的cgroup_subsys list

    /* The root cgroup for this hierarchy */
    struct cgroup top_cgroup;// 此hierarchy的root cgroup

    /* Tracks how many cgroups are currently defined in hierarchy.*/
    int number_of_cgroups;//此hierarchy cgroup 數目

    /* A list running through the active hierarchies */
    struct list_head root_list; //系統中hierarchy鏈表 

    /* All cgroups on this root, cgroup_mutex protected */
    struct list_head allcg_list;//此hierarchy包含的全部的cgroup

    /* Hierarchy-specific flags */
    unsigned long flags;

    /* IDs for cgroups in this hierarchy */
    struct ida cgroup_ida;

    /* The path to use for release notifications. */
    char release_agent_path[PATH_MAX];

    /* The name for this hierarchy - may be empty */
    char name[MAX_CGROUP_ROOT_NAMELEN];
};
  • cgroup_subsys

對應特定的子系統。ui

/*
 * Control Group subsystem type.
 * See Documentation/cgroups/cgroups.txt for details
 */

struct cgroup_subsys {
    struct cgroup_subsys_state *(*css_alloc)(struct cgroup *cgrp);
    int (*css_online)(struct cgroup *cgrp);
    void (*css_offline)(struct cgroup *cgrp);
    void (*css_free)(struct cgroup *cgrp);

    int (*can_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
    void (*cancel_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
    void (*attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
    void (*fork)(struct task_struct *task);
    void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp,
             struct task_struct *task);
    void (*bind)(struct cgroup *root);
    /*上面的針對不一樣的子系統指向不一樣的函數指針*/
    
    int subsys_id;// subsystem id
    int disabled;
    int early_init;//是否early_init
    /*
     * True if this subsys uses ID. ID is not available before cgroup_init()
     * (not available in early_init time.)
     */
    bool use_id;

    /*
     * If %false, this subsystem is properly hierarchical -
     * configuration, resource accounting and restriction on a parent
     * cgroup cover those of its children.  If %true, hierarchy support
     * is broken in some ways - some subsystems ignore hierarchy
     * completely while others are only implemented half-way.
     *
     * It's now disallowed to create nested cgroups if the subsystem is
     * broken and cgroup core will emit a warning message on such
     * cases.  Eventually, all subsystems will be made properly
     * hierarchical and this will go away.
     */
    bool broken_hierarchy;
    bool warned_broken_hierarchy;

#define MAX_CGROUP_TYPE_NAMELEN 32
    const char *name;

    /*
     * Link to parent, and list entry in parent's children.
     * Protected by cgroup_lock()
     */
    struct cgroupfs_root *root;//指向所屬的hierarchy
    struct list_head sibling;
    /* used when use_id == true */
    struct idr idr;
    spinlock_t id_lock;

    /* list of cftype_sets */
    struct list_head cftsets;

    /* base cftypes, automatically [de]registered with subsys itself */
    struct cftype *base_cftypes;
    struct cftype_set base_cftset;

    /* should be defined only by modular subsystems */
    struct module *module;
    }
  • cgroup_subsys_state
/* Per-subsystem/per-cgroup state maintained by the system. */
struct cgroup_subsys_state {
/*
 * The cgroup that this subsystem is attached to. Useful
 * for subsystems that want to know about the cgroup
 * hierarchy structure
 */
struct cgroup *cgroup;//此css關聯的cgroup. 1個cgroup可對應多個css

/*
 * State maintained by the cgroup system to allow subsystems
 * to be "busy". Should be accessed via css_get(),
 * css_tryget() and css_put().
 */

atomic_t refcnt;

unsigned long flags;
/* ID for this css, if possible */
struct css_id __rcu *id;

/* Used to put @cgroup->dentry on the last css_put() */
struct work_struct dput_work;
};

此外,還有幾個cgroup相關的全局變量this

/*
 * The "rootnode" hierarchy is the "dummy hierarchy", reserved for the
 * subsystems that are otherwise unattached - it never has more than a
 * single cgroup, and all tasks are part of that cgroup.
 * 初始化默認cgroupfs_root. 系統初始化時全部的subsystem都關聯到此hierarchy. 不能夠在默認
 * hierarchy上建立cgroup,所以其只有一個默認的root cgroup.
 */
static struct cgroupfs_root rootnode;

/* The default css_set - used by init and its children prior to any
 * hierarchies being mounted. It contains a pointer to the root state
 * for each subsystem. Also used to anchor the list of css_sets. Not
 * reference-counted, to improve performance when child cgroups
 * haven't been created.
 * 初始化默認的css_set. 在沒有hierarchy被mount以前,系統初始化時init及其子進程關聯此css_set。
 * init_css_set->subsys指向每一個subsys的root css.
 */
static struct css_set init_css_set;

/*
 * hash table for cgroup groups. This improves the performance to find
 * an existing css_set. This hash doesn't (currently) take into
 * account cgroups in empty hierarchies.
 * css_set的hash table.將task關聯到指定css,就是將task->cgroup指針指向一個
 * css_set. css_set_table以css[]爲key,相同的css集合,即爲同一個css_set. 當有task須要關聯到到一
 * 組css時,以css[]爲key在hash table中查找是否存在,存在直接引用此key的css_set,不然建立css_set
 * 並添加到hash table.
 * 
#define CSS_SET_HASH_BITS    7
static DEFINE_HASHTABLE(css_set_table, CSS_SET_HASH_BITS);
相關文章
相關標籤/搜索