Skip to content

Commit

Permalink
When in a softirq context, memory allocation should be atomic
Browse files Browse the repository at this point in the history
Eviction of flows based on TCP state machine happens in the softirq
context. The process of evicting a flow depends on the kernel work
queues, for which allocation of memory needs to happen. Under such
cases, the allocation should not wait. Hence, pass GFP_ATOMIC as the
allocation flag when in softirq context to indicate that the path is
not willing to block.

Change-Id: I2c56203c2666a981ff3218268611d95e18281151
Closes-Bug: #1618375
  • Loading branch information
anandhk-juniper committed Sep 2, 2016
1 parent c0f4500 commit c08c488
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 12 deletions.
3 changes: 1 addition & 2 deletions dp-core/vr_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1714,8 +1714,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
Expand Down
4 changes: 3 additions & 1 deletion dpdk/vr_dpdk_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions freebsd/vrouter_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions host/vrouter_host_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion include/vrouter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
16 changes: 12 additions & 4 deletions linux/vrouter_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c08c488

Please sign in to comment.