让程序跑在特定的cpu上在kernel space的实现

如果需要将程序跑在特定的cpu上,可以参考下面的code实现in_interrupt
int my_func_on_cpu(int cpu)
{
int err;
get_online_cpus();
if (!cpu_online(cpu))
err = -EINVAL;
else
if(in_interrupt())
err = work_on_cpu(cpu, __my_func_on_cpu, NULL);
else
smp_call_function_single(cpu, __my_func_on_cpu, &err,
true);
endif
put_online_cpus();
return err;
}
如果确定你的code 是在interrupt context 就用smp_call_function_single。如果跑在thread context就用work_on_cpu,因为work_on_cpu
可能会sleep,所以不能用在interrupt context中.
如果两种环境都有可能跑到就用上面这种方式就可以,即用in_interrupt()函数来确定是否在interrupt context 中.
long work_on_cpu(int cpu, long (*fn)(void *), void *arg)
{
struct work_for_cpu wfc = { .fn = fn, .arg = arg };


INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn);
schedule_work_on(cpu, &wfc.work);
flush_work(&wfc.work);
destroy_work_on_stack(&wfc.work);
return wfc.ret;
}


work_on_cpu 首先在stack上建议一个work_struct。
#define INIT_WORK_ONSTACK(_work, _func) \
__INIT_WORK((_work), (_func), 1)
我们没有定义CONFIG_LOCKDEP。所以我们走的是else的case
#ifdef CONFIG_LOCKDEP
#define __INIT_WORK(_work, _func, _onstack) \
do { \
static struct lock_class_key __key; \
\
__init_work((_work), _onstack); \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0); \
INIT_LIST_HEAD(&(_work)->entry); \
(_work)->func = (_func); \
} while (0)
#else
#define __INIT_WORK(_work, _func, _onstack) \
do { \
__init_work((_work), _onstack); \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
INIT_LIST_HEAD(&(_work)->entry); \
(_work)->func = (_func); \
} while (0)
#endif


这个workqueue的回调函数是
static void work_for_cpu_fn(struct work_struct *work)
{
struct work_for_cpu *wfc = container_of(work, struct work_for_cpu, work);


wfc->ret = wfc->fn(wfc->arg);
}


也就是直接调用用户注册的函数.
其次调用schedule_work_on(cpu, &wfc.work);来运行workqueue
static inline bool schedule_work_on(int cpu, struct work_struct *work)
{
return queue_work_on(cpu, system_wq, work);
}
schedule_work_on 是将我们前面在stack上建立的work_struct 放到system_wq 这个系统已经定义好的workqueue_struct 中来运行.
最后调用flush_work(&wfc.work);来等待wfc.work 执行完成.
由于我们的work_struct是建立在stack上的,因此work_on_cpu 函数返回的时候work_struct 就会被自动销毁
因此在没有定义CONFIG_DEBUG_OBJECTS_WORK来debug的时候destroy_work_on_stack是一个空函数



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值