percpu 变量总结

来源:互联网 发布:实战java高并发程序设 编辑:程序博客网 时间:2024/06/06 01:54
percpu 可以的接口可以分为新接口和旧接口目前旧借口的sample code如下:int cpu;tuners = kzalloc(sizeof(*tuners), GFP_KERNEL);if (!tuners)return -ENOMEM;cpu = get_cpu();idle_time = get_cpu_idle_time_us(cpu, NULL);put_cpu();这code 中可以通过get_cpu 得到当前cpu#define get_cpu()({ preempt_disable(); smp_processor_id(); })可以看到get_cpu 首先会通过preempt_disable 禁止内核抢占,然后调用smp_processor_id 返回当前cpu id。而与之对应的put_cpu 就是使能内核抢占.#define put_cpu()preempt_enable()新的percpu接口可以分为静态申请和动态申请静态percpu 可以通过DECLARE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu); 来申请可以通过fps = &per_cpu(bnx2fc_percpu, cpu);来读到这个percpu的数据到fps中而这里的#define per_cpu(var, cpu)(*per_cpu_ptr(&(var), cpu))可见per_cpu 只是per_cpu_ptr的一个包装,因此能用per_cpu访问的,都可以通过per_cpu_ptr 来访问#define per_cpu_ptr(ptr, cpu)\({\__verify_pcpu_ptr(ptr);\SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));\})例如下例子中就通过per_cpu_ptr得到acpi_perf_data 这个变量在cpu上的值static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy){perf = per_cpu_ptr(acpi_perf_data, cpu);}更进一步是采用get_cpu_ptr得到percpu的值#define get_cpu_ptr(var)\({\preempt_disable();\this_cpu_ptr(var);\})get_cpu_ptr 默认是获取当前cpu上的值int squashfs_decompress(struct squashfs_sb_info *msblk, struct buffer_head **bh,int b, int offset, int length, struct squashfs_page_actor *output){struct squashfs_stream *stream = get_cpu_ptr(percpu);}除了静态定义外,percpu变量可以在运行是创建alloc_percpu 可以在运行是创建percpu变量,释放percpu占用的空间可以采用free_percpu使用的例子如下:static __net_init int ipv4_mib_init_net(struct net *net){int i;net->mib.tcp_statistics = alloc_percpu(struct tcp_mib);if (!net->mib.tcp_statistics)goto err_tcp_mib;net->mib.ip_statistics = alloc_percpu(struct ipstats_mib);if (!net->mib.ip_statistics)goto err_ip_mib;for_each_possible_cpu(i) {struct ipstats_mib *af_inet_stats;af_inet_stats = per_cpu_ptr(net->mib.ip_statistics, i);u64_stats_init(&af_inet_stats->syncp);}net->mib.net_statistics = alloc_percpu(struct linux_mib);if (!net->mib.net_statistics)goto err_net_mib;net->mib.udp_statistics = alloc_percpu(struct udp_mib);if (!net->mib.udp_statistics)goto err_udp_mib;net->mib.udplite_statistics = alloc_percpu(struct udp_mib);if (!net->mib.udplite_statistics)goto err_udplite_mib;net->mib.icmp_statistics = alloc_percpu(struct icmp_mib);if (!net->mib.icmp_statistics)goto err_icmp_mib;net->mib.icmpmsg_statistics = kzalloc(sizeof(struct icmpmsg_mib),      GFP_KERNEL);if (!net->mib.icmpmsg_statistics)goto err_icmpmsg_mib;tcp_mib_init(net);return 0;err_icmpmsg_mib:free_percpu(net->mib.icmp_statistics);err_icmp_mib:free_percpu(net->mib.udplite_statistics);err_udplite_mib:free_percpu(net->mib.udp_statistics);err_udp_mib:free_percpu(net->mib.net_statistics);err_net_mib:free_percpu(net->mib.ip_statistics);err_ip_mib:free_percpu(net->mib.tcp_statistics);err_tcp_mib:return -ENOMEM;}

原创粉丝点击