亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

echo 0 > /sys/devices/system/cpu/cpuX/online

2019-11-09 14:50:46
字體:
來源:轉載
供稿:網友
當通過下面的code是cpu offline的話。echo 0 > /sys/devices/system/cpu/cpuX/online具體的code flow如下:int device_add(struct device *dev)->device_create_file而dev_attr_onlline 就是按照下面的方式定義的static ssize_t online_store(struct device *dev, struct device_attribute *attr,                const char *buf, size_t count){    bool val;    int ret;    ret = strtobool(buf, &val);    if (ret < 0)        return ret;    ret = lock_device_hotplug_sysfs();    if (ret)        return ret;    ret = val ? device_online(dev) : device_offline(dev);    unlock_device_hotplug();    return ret < 0 ? ret : count;}static DEVICE_ATTR_RW(online);當echo 0的時候選擇device_online,否則device_offlineint device_offline(struct device *dev){    int ret;    if (dev->offline_disabled)        return -EPERM;    ret = device_for_each_child(dev, NULL, device_check_offline);    if (ret)        return ret;    device_lock(dev);    if (device_supports_offline(dev)) {        if (dev->offline) {            ret = 1;        } else {            ret = dev->bus->offline(dev);            if (!ret) {                kobject_uevent(&dev->kobj, KOBJ_OFFLINE);                dev->offline = true;            }        }    }    device_unlock(dev);    return ret;}可見是調用的bus->offline而cpu的bus定義如下:struct bus_type cpu_subsys = {    .name = "cpu",    .dev_name = "cpu",    .match = cpu_subsys_match,#ifdef CONFIG_HOTPLUG_CPU    .online = cpu_subsys_online,    .offline = cpu_subsys_offline,#endif};最終會調用cpu_subsys_offline->cpu_down->do_cpu_down->_cpu_down->cpuhp_down_callbacksstatic int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,                 bool bringup, struct hlist_node *node){    struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);    struct cpuhp_step *step = cpuhp_get_step(state);    int (*cbm)(unsigned int cpu, struct hlist_node *node);    int (*cb)(unsigned int cpu);    int ret, cnt;    if (!step->multi_instance) {        cb = bringup ? step->startup.single : step->teardown.single;        if (!cb)            return 0;        trace_cpuhp_enter(cpu, st->target, state, cb);        ret = cb(cpu);        trace_cpuhp_exit(cpu, st->state, state, ret);        return ret;    }    cbm = bringup ? step->startup.multi : step->teardown.multi;    if (!cbm)        return 0;    }在cpuhp_invoke_callback 中我們假定step->multi_instance == 0,因此cb= step->teardown.single其是在cpuhp_bp_states 數組中定義的    [CPUHP_TEARDOWN_CPU] = {        .name            = "cpu:teardown",        .startup.single        = NULL,        .teardown.single    = takedown_cpu,        .cant_stop        = true,    },takedown_cpu->__cpu_die->op_cpu_kill其中op_cpu_kill 在arm64下定義如下:static int op_cpu_kill(unsigned int cpu){    /*     * If we have no means of synchronising with the dying CPU, then assume     * that it is really dead. We can only wait for an arbitrary length of     * time and hope that it's dead, so let's skip the wait and just hope.     */    if (!cpu_ops[cpu]->cpu_kill)        return 0;    return cpu_ops[cpu]->cpu_kill(cpu);}而在smp_cpu_setup->cpu_read_ops來決定cpu_ops的值int __init cpu_read_ops(int cpu){    const char *enable_method = cpu_read_enable_method(cpu);    if (!enable_method)        return -ENODEV;    cpu_ops[cpu] = cpu_get_ops(enable_method);    if (!cpu_ops[cpu]) {        PR_warn("Unsupported enable-method: %s/n", enable_method);        return -EOPNOTSUPP;    }    return 0;}enable_method 是會從deviceTree或者acpi表中parse 當前的enable_methodstatic const char *__init cpu_read_enable_method(int cpu){    const char *enable_method;    if (acpi_disabled) {        struct device_node *dn = of_get_cpu_node(cpu, NULL);        if (!dn) {            if (!cpu)                pr_err("Failed to find device node for boot cpu/n");            return NULL;        }        enable_method = of_get_property(dn, "enable-method", NULL);        if (!enable_method) {            /*             * The boot CPU may not have an enable method (e.g.             * when spin-table is used for secondaries).             * Don't warn spuriously.             */            if (cpu != 0)                pr_err("%s: missing enable-method property/n",                    dn->full_name);        }    } else {        enable_method = acpi_get_enable_method(cpu);        if (!enable_method) {            /*             * In ACPI systems the boot CPU does not require             * checking the enable method since for some             * boot protocol (ie parking protocol) it need not             * be initialized. Don't warn spuriously.             */            if (cpu != 0)                pr_err("Unsupported ACPI enable-method/n");        }    }    return enable_method;}我們以acpi為例static inline const char *acpi_get_enable_method(int cpu){    if (acpi_psci_present())        return "psci";    if (acpi_parking_protocol_valid(cpu))        return "parking-protocol";    return NULL;}可見cpu_ops分為兩類,psci和parking-protocol,目前主流是psci,具體是在acpi的FADT表中判斷當前是否支持psci的bool __init acpi_psci_present(void){    return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT;}決定是psci后,因此cpu_ops就是cpu_psci_opsstatic const struct cpu_Operations *acpi_supported_cpu_ops[] __initconst = {#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL    &acpi_parking_protocol_ops,#endif    &cpu_psci_ops,    NULL,};const struct cpu_operations cpu_psci_ops = {    .name        = "psci",#ifdef CONFIG_CPU_IDLE    .cpu_init_idle    = psci_cpu_init_idle,    .cpu_suspend    = psci_cpu_suspend_enter,#endif    .cpu_init    = cpu_psci_cpu_init,    .cpu_prepare    = cpu_psci_cpu_prepare,    .cpu_boot    = cpu_psci_cpu_boot,#ifdef CONFIG_HOTPLUG_CPU    .cpu_disable    = cpu_psci_cpu_disable,    .cpu_die    = cpu_psci_cpu_die,    .cpu_kill    = cpu_psci_cpu_kill,#endif};psci的cpu_kill是cpu_psci_cpu_killstatic int cpu_psci_cpu_kill(unsigned int cpu){    int err, i;    if (!psci_ops.affinity_info)        return 0;    /*     * cpu_kill could race with cpu_die and we can     * potentially end up declaring this cpu undead     * while it is dying. So, try again a few times.     */    for (i = 0; i < 10; i++) {        err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);        if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) {            pr_info("CPU%d killed./n", cpu);            return 0;        }        msleep(10);        pr_info("Retrying again to check for CPU kill/n");    }    pr_warn("CPU%d may not have shut down cleanly (AFFINITY_INFO reports %d)/n",            cpu, err);    return -ETIMEDOUT;}有調用psci_ops.affinity_info    psci_ops.affinity_info = psci_affinity_info;可見最后是給ATF發信號讓ATF來關掉cpu的。static int psci_affinity_info(unsigned long target_affinity,        unsigned long lowest_affinity_level){    return invoke_psci_fn(PSCI_FN_NATIVE(0_2, AFFINITY_INFO),                  target_affinity, lowest_affinity_level, 0);}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91网站免费看| 成人免费视频97| 亚洲18私人小影院| 亚洲午夜精品久久久久久久久久久久| 国产午夜精品全部视频在线播放| 欧美麻豆久久久久久中文| 黑人巨大精品欧美一区二区一视频| 色在人av网站天堂精品| 亚洲第一页中文字幕| 日韩久久免费电影| 国产精品久久久久免费a∨| 亚洲二区中文字幕| 91成人福利在线| 久久综合电影一区| 国内精品模特av私拍在线观看| 精品久久久久久亚洲国产300| 日韩动漫免费观看电视剧高清| 国产区亚洲区欧美区| 欧美精品在线免费观看| 97**国产露脸精品国产| 中文字幕久久亚洲| 美女av一区二区三区| 亚洲成人精品视频在线观看| 中文字幕亚洲二区| 亚洲美女在线观看| 亚洲欧美www| 国产精品久久久久久亚洲影视| 欧美激情高清视频| 国产精品爱久久久久久久| 欧美在线影院在线视频| 7m精品福利视频导航| 欧美日韩亚洲高清| 亚洲а∨天堂久久精品喷水| 成人国产精品久久久| 尤物精品国产第一福利三区| 久久夜色精品亚洲噜噜国产mv| 精品久久久久久久久久| 亚洲视频在线看| 久久97久久97精品免视看| 日韩欧美亚洲范冰冰与中字| 国产精品视频精品视频| 国产一区二区在线免费| 亚洲欧美中文日韩在线| 欧美日韩性生活视频| 久久精品成人欧美大片| 久久久噜噜噜久久久| 亚洲一区二区三区在线免费观看| 欧美成人精品三级在线观看| 欧美中文字幕视频| 亚洲精品午夜精品| 欧美成人免费观看| 欧美大码xxxx| 中文字幕无线精品亚洲乱码一区| 亚洲欧洲日韩国产| 92版电视剧仙鹤神针在线观看| 亚洲韩国青草视频| 亚洲精品www久久久久久广东| 亚洲欧美日韩在线一区| 久久精品国产亚洲精品2020| 久久免费少妇高潮久久精品99| 日韩欧美在线视频观看| 成人av色在线观看| 黑人巨大精品欧美一区二区一视频| 亚洲国产精品资源| 成人性教育视频在线观看| 爽爽爽爽爽爽爽成人免费观看| 久久人人爽人人爽人人片亚洲| 国产精品一区二区久久精品| 精品丝袜一区二区三区| 亚洲精品动漫100p| 国产日韩换脸av一区在线观看| 亚洲精品福利免费在线观看| 久久久亚洲网站| 一区二区在线视频播放| 91成人在线观看国产| 欧美日韩在线影院| 欧美黑人一级爽快片淫片高清| 国产免费观看久久黄| 中文字幕日韩专区| 亚洲日韩欧美视频| 国产精品人成电影| 亚洲精品91美女久久久久久久| 少妇久久久久久| 久久亚洲成人精品| 国产午夜精品视频免费不卡69堂| 欧美激情精品久久久久久蜜臀| 久久天天躁狠狠躁夜夜av| 超薄丝袜一区二区| 在线播放国产一区中文字幕剧情欧美| 亚洲成人精品在线| 社区色欧美激情 | 黄网动漫久久久| 亚洲va久久久噜噜噜| 日韩美女激情视频| 91亚洲人电影| 中文字幕亚洲欧美在线| 欧美国产视频日韩| 国产日韩在线播放| 色偷偷亚洲男人天堂| 色狠狠av一区二区三区香蕉蜜桃| 美女久久久久久久久久久| 亚洲欧洲国产一区| 亚洲精美色品网站| 91干在线观看| 欧美激情一级二级| 亚洲男人的天堂网站| 成人综合网网址| 亚洲国产成人精品久久久国产成人一区| 成人黄色生活片| 国产人妖伪娘一区91| 欧美日韩国产麻豆| 亚洲欧美一区二区精品久久久| 国产精品老女人精品视频| 久久免费在线观看| 欧美一级大片在线免费观看| 亚洲深夜福利在线| 91在线精品视频| 欧美性资源免费| 国产精品三级美女白浆呻吟| 日本一区二区在线播放| 国产日韩中文字幕| 日韩大片免费观看视频播放| 成人激情视频在线观看| 日韩激情片免费| 91久久精品国产91久久性色| 操人视频在线观看欧美| 欧美激情中文网| 欧美在线视频a| 亚洲色图欧美制服丝袜另类第一页| 国产精品欧美亚洲777777| 国产一区二区三区在线观看视频| 91av在线播放视频| 国产免费观看久久黄| 亚洲999一在线观看www| 欧美日韩国产色视频| 亚洲综合在线播放| 中文字幕日韩有码| 这里只有精品在线观看| 久久人人爽亚洲精品天堂| 国产91精品青草社区| 国产精品国产三级国产aⅴ9色| 日韩av免费在线观看| 日韩视频在线免费| 日本精品一区二区三区在线播放视频| 一区三区二区视频| 久久影视电视剧免费网站清宫辞电视| 美日韩丰满少妇在线观看| 亚洲精品v天堂中文字幕| 久久久av亚洲男天堂| 久久久久亚洲精品成人网小说| 国产精品久久久久久久久久ktv| 一区二区亚洲精品国产| 久久久久久中文| 欧美激情综合色| 国产69精品久久久久久| 欧美性xxxx极品hd欧美风情| 亚洲少妇中文在线| 成人黄色免费片| 欧美亚洲国产视频小说| 久久久久五月天| 亚洲第一男人天堂| 欧美亚洲成人xxx| 高清欧美电影在线| 亚洲国产精品高清久久久|