diff --git a/dp-core/vr_flow.c b/dp-core/vr_flow.c index 0a25ba197..02db8ca6b 100644 --- a/dp-core/vr_flow.c +++ b/dp-core/vr_flow.c @@ -1698,8 +1698,7 @@ __vr_flow_schedule_transition(struct vrouter *router, struct vr_flow_entry *fe, } flmd->flmd_defer_data = defer; - vr_schedule_work(vr_get_cpu(), vr_flow_work, (void *)flmd); - return 0; + return vr_schedule_work(vr_get_cpu(), vr_flow_work, (void *)flmd); } static int diff --git a/dpdk/vr_dpdk_host.c b/dpdk/vr_dpdk_host.c index 54edc97b4..b42ef0d21 100644 --- a/dpdk/vr_dpdk_host.c +++ b/dpdk/vr_dpdk_host.c @@ -502,11 +502,13 @@ dpdk_get_mono_time(unsigned int *sec, unsigned int *nsec) } /* Work callback called on NetLink lcore */ -static void +static int dpdk_schedule_work(unsigned int cpu, void (*fn)(void *), void *arg) { /* no RCU reader lock needed, just do the work */ fn(arg); + + return 0; } static void diff --git a/freebsd/vrouter_mod.c b/freebsd/vrouter_mod.c index 7381c4ec3..0d0ad2b31 100644 --- a/freebsd/vrouter_mod.c +++ b/freebsd/vrouter_mod.c @@ -331,11 +331,12 @@ fh_get_cpu(void) return (cpuid); } -static void +static int fh_schedule_work(unsigned int cpu, void (*fn)(void *), void *arg) { - vr_log(VR_ERR, "%s: not implemented\n", __func__); + + return -EOPNOTSUPP; } static void diff --git a/host/vrouter_host_mod.c b/host/vrouter_host_mod.c index 6c4227505..e91780a9d 100644 --- a/host/vrouter_host_mod.c +++ b/host/vrouter_host_mod.c @@ -225,10 +225,10 @@ vr_lib_get_cpu(void) return 0; } -static void +static int vr_lib_schedule_work(unsigned int cpu, void (*fn)(void *), void *arg) { - return; + return -EOPNOTSUPP; } static void diff --git a/include/vrouter.h b/include/vrouter.h index 70bb75e5a..2ce15892f 100644 --- a/include/vrouter.h +++ b/include/vrouter.h @@ -159,7 +159,7 @@ struct host_os { unsigned int (*hos_pgso_size)(struct vr_packet *); unsigned int (*hos_get_cpu)(void); - void (*hos_schedule_work)(unsigned int, void (*)(void *), void *); + int (*hos_schedule_work)(unsigned int, void (*)(void *), void *); void (*hos_delay_op)(void); void (*hos_defer)(struct vrouter *, vr_defer_cb, void *); void *(*hos_get_defer_data)(unsigned int); diff --git a/linux/vrouter_mod.c b/linux/vrouter_mod.c index c18db6f1a..b6e956a09 100644 --- a/linux/vrouter_mod.c +++ b/linux/vrouter_mod.c @@ -416,20 +416,28 @@ lh_work(struct work_struct *work) return; } -static void +static int lh_schedule_work(unsigned int cpu, void (*fn)(void *), void *arg) { - struct work_arg *wa = kzalloc(sizeof(*wa), GFP_KERNEL); + unsigned int alloc_flag; + struct work_arg *wa; + + if (in_softirq()) { + alloc_flag = GFP_ATOMIC; + } else { + alloc_flag = GFP_KERNEL; + } + wa = kzalloc(sizeof(*wa), alloc_flag); if (!wa) - return; + return -ENOMEM; wa->fn = fn; wa->wa_arg = arg; INIT_WORK(&wa->wa_work, lh_work); schedule_work_on(cpu, &wa->wa_work); - return; + return 0; } static void