(arg == 0 && kind == DTRACEACT_PRINTA));
#endif
- act = kzalloc(sizeof (dtrace_actdesc_t), GFP_KERNEL);
+ act = vzalloc(sizeof (dtrace_actdesc_t));
+ if (act == NULL)
+ return NULL;
+
act->dtad_kind = kind;
act->dtad_ntuple = ntuple;
act->dtad_uarg = uarg;
#endif
if (str != NULL)
- kfree(str);
+ vfree(str);
}
- kfree(act);
+ vfree(act);
}
size = sizeof(dtrace_eprobedesc_t) +
(epdesc.dtepd_nrecs * sizeof(dtrace_recdesc_t));
- buf = kmalloc(size, GFP_KERNEL);
- dest = buf;
+ buf = vmalloc(size);
+ if (buf == NULL)
+ return -ENOMEM;
+ dest = buf;
memcpy(dest, &epdesc, sizeof(epdesc));
dest += offsetof(dtrace_eprobedesc_t, dtepd_rec[0]);
if (copy_to_user(argp, buf,
(uintptr_t)(dest - (uint8_t *)buf)) != 0) {
- kfree(buf);
+ vfree(buf);
return -EFAULT;
}
- kfree(buf);
+ vfree(buf);
return 0;
}
size = sizeof(dtrace_aggdesc_t) +
(aggdesc.dtagd_nrecs * sizeof(dtrace_recdesc_t));
- buf = kmalloc(size, GFP_KERNEL);
- dest = buf;
+ buf = vmalloc(size);
+ if (buf == NULL)
+ return -ENOMEM;
+ dest = buf;
memcpy(dest, &aggdesc, sizeof(aggdesc));
dest += offsetof(dtrace_aggdesc_t, dtagd_rec[0]);
if (copy_to_user(argp, buf,
(uintptr_t)(dest - (uint8_t *)buf)) != 0) {
- kfree(buf);
+ vfree(buf);
return -EFAULT;
}
- kfree(buf);
+ vfree(buf);
return 0;
}
mutex_lock(&dtrace_lock);
dof = dtrace_dof_create(state);
mutex_unlock(&dtrace_lock);
+ if (dof == NULL)
+ return -ENOMEM;
len = min(hdr.dofh_loadsz, dof->dofh_loadsz);
rval = copy_to_user(argp, dof, len);
dtrace_toxranges_max <<= 1;
nsize = dtrace_toxranges_max * sizeof(dtrace_toxrange_t);
- range = kzalloc(nsize, GFP_KERNEL);
+ range = vzalloc(nsize);
+ if (range == NULL) {
+ pr_warn("Failed to add toxic range: out of memory\n");
+ return;
+ }
if (dtrace_toxrange != NULL) {
ASSERT(osize != 0);
memcpy(range, dtrace_toxrange, osize);
- kfree(dtrace_toxrange);
+ vfree(dtrace_toxrange);
}
dtrace_toxrange = range;
dtrace_helptrace_buffer = vzalloc(dtrace_helptrace_bufsize);
dtrace_helptrace_next = 0;
+
+ if (dtrace_helptrace_buffer == NULL) {
+ pr_warn("Cannot allocate helptrace buffer; "
+ "disabling dtrace_helptrace\n");
+ dtrace_helptrace_enabled = 0;
+ }
}
#ifdef FIXME
osz = otlocals * sizeof(dtrace_difv_t);
nsz = ntlocals * sizeof(dtrace_difv_t);
- tlocals = kzalloc(nsz, GFP_KERNEL);
+ tlocals = vzalloc(nsz);
if (osz != 0) {
memcpy(tlocals, vstate->dtvs_tlocals,
osz);
- kfree(vstate->dtvs_tlocals);
+ vfree(vstate->dtvs_tlocals);
}
vstate->dtvs_tlocals = tlocals;
oldsize = oldsvars * sizeof(dtrace_statvar_t *);
newsize = newsvars * sizeof(dtrace_statvar_t *);
- statics = kzalloc(newsize, GFP_KERNEL);
+ statics = vzalloc(newsize);
if (oldsize != 0) {
memcpy(statics, *svarp, oldsize);
- kfree(*svarp);
+ vfree(*svarp);
}
*svarp = statics;
}
if ((svar = (*svarp)[id]) == NULL) {
- svar = kzalloc(sizeof(dtrace_statvar_t), GFP_KERNEL);
+ svar = vzalloc(sizeof(dtrace_statvar_t));
svar->dtsv_var = *v;
if ((svar->dtsv_size = dsize) != 0) {
svar->dtsv_data =
- (uint64_t)(uintptr_t)kzalloc(
- dsize, GFP_KERNEL);
+ (uint64_t)(uintptr_t)vzalloc(dsize);
}
(*svarp)[id] = svar;
if (svar->dtsv_size != 0) {
ASSERT((void *)(uintptr_t)svar->dtsv_data != NULL);
- kfree((void *)(uintptr_t)svar->dtsv_data);
+ vfree((void *)(uintptr_t)svar->dtsv_data);
}
- kfree(svar);
+ vfree(svar);
svarp[id] = NULL;
}
- kfree(dp->dtdo_buf);
- kfree(dp->dtdo_inttab);
- kfree(dp->dtdo_strtab);
- kfree(dp->dtdo_vartab);
- kfree(dp);
+ vfree(dp->dtdo_buf);
+ vfree(dp->dtdo_inttab);
+ vfree(dp->dtdo_strtab);
+ vfree(dp->dtdo_vartab);
+ vfree(dp);
}
void dtrace_difo_release(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
ASSERT(MUTEX_HELD(&dtrace_lock));
- dof = kmalloc(len, GFP_KERNEL);
+ dof = vmalloc(len);
+ if (dof == NULL)
+ return NULL;
+
dof->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0;
dof->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1;
dof->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2;
return NULL;
}
- dof = kmalloc(hdr.dofh_loadsz, GFP_KERNEL);
+ dof = vmalloc(hdr.dofh_loadsz);
+ if (dof == NULL) {
+ *errp = -ENOMEM;
+ return NULL;
+ }
if (copy_from_user(dof, argp, hdr.dofh_loadsz) != 0 ||
dof->dofh_loadsz != hdr.dofh_loadsz) {
- kfree(dof);
+ vfree(dof);
*errp = -EFAULT;
return NULL;
}
return NULL;
}
- dof = kmalloc(loadsz, GFP_KERNEL);
+ dof = vmalloc(loadsz);
+ if (dof == NULL) {
+ dtrace_dof_error(NULL, "out-of-memory");
+ return NULL;
+ }
memcpy(dof, buf, loadsz);
#ifdef FIXME
ddi_prop_free(buf);
void dtrace_dof_destroy(dof_hdr_t *dof)
{
- kfree(dof);
+ vfree(dof);
}
/*
dofd = (dof_difohdr_t *)(uintptr_t)(daddr + sec->dofs_offset);
n = (sec->dofs_size - sizeof(*dofd)) / sizeof(dof_secidx_t) + 1;
- dp = kzalloc(sizeof(dtrace_difo_t), GFP_KERNEL);
+ dp = vzalloc(sizeof(dtrace_difo_t));
+ if (dp == NULL) {
+ dtrace_dof_error(dof, "out-of-memory");
+ return NULL;
+ }
dp->dtdo_rtype = dofd->dofd_rtype;
for (l = 0; l < n; l++) {
}
*lenp = subsec->dofs_size;
- *bufp = kmalloc(subsec->dofs_size, GFP_KERNEL);
+ *bufp = vmalloc(subsec->dofs_size);
+ if (*bufp == NULL) {
+ dtrace_dof_error(dof, "out-of-memory");
+ goto err;
+ }
memcpy(*bufp,
(char *)(uintptr_t)(daddr + subsec->dofs_offset),
subsec->dofs_size);
return dp;
err:
- kfree(dp->dtdo_buf);
- kfree(dp->dtdo_inttab);
- kfree(dp->dtdo_strtab);
- kfree(dp->dtdo_vartab);
+ if (dp->dtdo_buf != NULL)
+ vfree(dp->dtdo_buf);
+ if (dp->dtdo_inttab != NULL)
+ vfree(dp->dtdo_inttab);
+ if (dp->dtdo_strtab != NULL)
+ vfree(dp->dtdo_strtab);
+ if (dp->dtdo_vartab != NULL)
+ vfree(dp->dtdo_vartab);
+
+ vfree(dp);
- kfree(dp);
return NULL;
}
}
i -= desc->dofa_arg;
- fmt = kmalloc(i + 1, GFP_KERNEL);
+ fmt = vmalloc(i + 1);
+ if (fmt == NULL) {
+ dtrace_dof_error(dof, "out-of-memory");
+ goto err;
+ }
memcpy(fmt, &str[desc->dofa_arg], i + 1);
arg = (uint64_t)(uintptr_t)fmt;
} else {
act = dtrace_actdesc_create(kind, desc->dofa_ntuple,
desc->dofa_uarg, arg);
+ if (act == NULL)
+ goto err;
if (last != NULL)
last->dtad_next = act;
if (sec == NULL)
return NULL;
- ep = kzalloc(sizeof(dtrace_ecbdesc_t), GFP_KERNEL);
+ ep = vzalloc(sizeof(dtrace_ecbdesc_t));
+ if (ep == NULL)
+ return NULL;
ep->dted_uarg = ecb->dofe_uarg;
desc = &ep->dted_probe;
err:
if (pred != NULL)
dtrace_predicate_release(pred, vstate);
- kfree(ep);
+ vfree(ep);
return NULL;
}
if ((enab = *enabp) == NULL)
enab = *enabp = dtrace_enabling_create(vstate);
+ if (enab == NULL)
+ return -1;
+
for (i = 0; i < dof->dofh_secnum; i++) {
dof_sec_t *sec =
(dof_sec_t *)(daddr +
ASSERT(curr->dtrace_helpers == NULL);
dth = vzalloc(sizeof(dtrace_helpers_t));
+ if (dth == NULL)
+ return NULL;
+
dth->dthps_actions = vzalloc(sizeof(dtrace_helper_action_t *) *
DTRACE_NHELPER_ACTIONS);
+ if (dth->dthps_actions == NULL) {
+ vfree(dth);
+ return NULL;
+ }
curr->dtrace_helpers = dth;
dtrace_helpers++;
return -ENOSPC;
helper = vzalloc(sizeof(dtrace_helper_action_t));
+ if (helper == NULL)
+ return -ENOMEM;
+
helper->dtha_generation = dth->dthps_generation;
if ((pred = ep->dted_pred.dtpdd_predicate) != NULL) {
helper->dtha_actions = vzalloc(sizeof(dtrace_difo_t *) *
(helper->dtha_nactions = nactions));
+ if (helper->dtha_actions == NULL)
+ goto err;
for (act = ep->dted_action, i = 0; act != NULL; act = act->dtad_next) {
dtrace_difo_hold(act->dtad_difo);
err:
dtrace_helper_action_destroy(helper, vstate);
+ if (helper->dtha_actions != NULL)
+ vfree(helper->dtha_actions);
+ else
+ return -ENOMEM;
+
return -EINVAL;
}
}
hprov = vzalloc(sizeof(dtrace_helper_provider_t));
+ if (hprov == NULL)
+ return -ENOMEM;
hprov->dthp_prov = *dofhp;
hprov->dthp_ref = 1;
hprov->dthp_generation = gen;
dth->dthps_provs = vzalloc(dth->dthps_maxprovs *
sizeof(dtrace_helper_provider_t *));
+ if (dth->dthps_provs == NULL) {
+ vfree(hprov);
+ return -ENOMEM;
+ }
if (tmp_provs != NULL) {
memcpy(dth->dthps_provs, tmp_provs,
if ((dth = current->dtrace_helpers) == NULL)
dth = dtrace_helpers_create(current);
+ if (dth == NULL) {
+ dtrace_dof_destroy(dof);
+ return -1;
+ }
+
vstate = &dth->dthps_vstate;
if ((rv = dtrace_dof_slurp(dof, vstate, NULL, &enab,
dtrace_state_t *state = ecb->dte_state;
int err;
- agg = kzalloc(sizeof(dtrace_aggregation_t), GFP_KERNEL);
+ agg = vzalloc(sizeof(dtrace_aggregation_t));
+ if (agg == NULL)
+ return NULL;
+
agg->dtag_ecb = ecb;
ASSERT(DTRACEACT_ISAGG(desc->dtad_kind));
ASSERT(ntuple != 0);
err:
- kfree(agg);
+ vfree(agg);
return NULL;
success:
idr_remove(&state->dts_agg_idr, agg->dtag_id);
state->dts_naggs--;
- kfree(agg);
+ vfree(agg);
}
static int dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc)
}
}
- action = kzalloc(sizeof(dtrace_action_t), GFP_KERNEL);
+ action = vzalloc(sizeof(dtrace_action_t));
+ if (action == NULL)
+ return -ENOMEM;
+
action->dta_rec.dtrd_size = size;
}
if (DTRACEACT_ISAGG(act->dta_kind))
dtrace_ecb_aggregation_destroy(ecb, act);
else
- kfree(act);
+ vfree(act);
}
}
ASSERT(MUTEX_HELD(&dtrace_lock));
- ecb = kzalloc(sizeof(dtrace_ecb_t), GFP_KERNEL);
+ ecb = vzalloc(sizeof(dtrace_ecb_t));
+ if (ecb == NULL)
+ return NULL;
+
ecb->dte_predicate = NULL;
ecb->dte_probe = probe;
ecb->dte_size = ecb->dte_needed = sizeof(dtrace_epid_t);
necbs = 1;
}
- ecbs = kcalloc(necbs, sizeof(*ecbs), GFP_KERNEL);
+ ecbs = vzalloc(necbs * sizeof(*ecbs));
if (oecbs != NULL)
memcpy(ecbs, oecbs, state->dts_necbs * sizeof(*ecbs));
if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE)
dtrace_sync();
- kfree(oecbs);
+ vfree(oecbs);
}
dtrace_membar_producer();
ASSERT(state->dts_ecbs[epid - 1] == ecb);
state->dts_ecbs[epid - 1] = NULL;
- kfree(ecb);
+ vfree(ecb);
}
void dtrace_ecb_resize(dtrace_ecb_t *ecb)
{
dtrace_enabling_t *enab;
- enab = kzalloc(sizeof (dtrace_enabling_t), GFP_KERNEL);
+ enab = vzalloc(sizeof (dtrace_enabling_t));
+ if (enab == NULL)
+ return NULL;
+
enab->dten_vstate = vstate;
return enab;
ASSERT(enab->dten_ndesc < enab->dten_maxdesc);
nsize = enab->dten_maxdesc * sizeof (dtrace_enabling_t *);
- ndesc = kzalloc(nsize, GFP_KERNEL);
+ ndesc = vzalloc(nsize);
memcpy(ndesc, enab->dten_desc, osize);
- kfree(enab->dten_desc);
+ vfree(enab->dten_desc);
enab->dten_desc = ndesc;
enab->dten_desc[enab->dten_ndesc++] = ecb;
* We're going to create a new ECB description that matches the
* specified ECB in every way, but has the specified probe description.
*/
- new = kzalloc(sizeof (dtrace_ecbdesc_t), GFP_KERNEL);
+ new = vzalloc(sizeof (dtrace_ecbdesc_t));
if ((pred = ecb->dted_pred.dtpdd_predicate) != NULL)
dtrace_predicate_hold(pred);
dtrace_actdesc_release(act, vstate);
}
- kfree(ep);
+ vfree(ep);
}
- kfree(enab->dten_desc);
+ vfree(enab->dten_desc);
/*
* If this was a retained enabling, decrement the dts_nretained count
enab->dten_next->dten_prev = enab->dten_prev;
}
- kfree(enab);
+ vfree(enab);
}
int dtrace_enabling_retain(dtrace_enabling_t *enab)
ASSERT(strlen(match->dtpd_name) < DTRACE_NAMELEN);
new = dtrace_enabling_create(&state->dts_vstate);
+ if (new == NULL)
+ return -ENOMEM;
/*
* Iterate over all retained enablings, looking for enablings that
uint16_t ndx;
fmt = dtrace_strdup(str);
+ if (fmt == NULL)
+ return 0;
for (ndx = 0; ndx < state->dts_nformats; ndx++) {
if (state->dts_formats[ndx] == NULL) {
return 0;
}
- ndx = state->dts_nformats++;
- new = kmalloc((ndx + 1) * sizeof (char *), GFP_KERNEL);
+ ndx = state->dts_nformats;
+ new = vmalloc((ndx + 1) * sizeof (char *));
+ if (new == NULL) {
+ kfree(fmt);
+ return 0;
+ }
+
+ state->dts_nformats++;
if (state->dts_formats != NULL) {
ASSERT(ndx != 0);
memcpy(new, state->dts_formats, ndx * sizeof (char *));
- kfree(state->dts_formats);
+ vfree(state->dts_formats);
}
state->dts_formats = new;
kfree(fmt);
}
- kfree(state->dts_formats);
+ vfree(state->dts_formats);
state->dts_nformats = 0;
state->dts_formats = NULL;
}
dtrace_hash_t *dtrace_hash_create(uintptr_t stroffs, uintptr_t nextoffs,
uintptr_t prevoffs)
{
- dtrace_hash_t *hash = kzalloc(sizeof (dtrace_hash_t), GFP_KERNEL);
+ dtrace_hash_t *hash = vzalloc(sizeof(dtrace_hash_t));
+
+ if (hash == NULL)
+ return NULL;
hash->dth_stroffs = stroffs;
hash->dth_nextoffs = nextoffs;
hash->dth_size = 1;
hash->dth_mask = hash->dth_size - 1;
- hash->dth_tab = kzalloc(hash->dth_size *
- sizeof (dtrace_hashbucket_t *), GFP_KERNEL);
+ hash->dth_tab = vzalloc(hash->dth_size *
+ sizeof(dtrace_hashbucket_t *));
+
+ if (hash->dth_tab == NULL) {
+ vfree(hash);
+ return NULL;
+ }
return hash;
}
-static void dtrace_hash_resize(dtrace_hash_t *hash)
+static int dtrace_hash_resize(dtrace_hash_t *hash)
{
int size = hash->dth_size, i, ndx;
int new_size = hash->dth_size << 1;
ASSERT((new_size & new_mask) == 0);
- new_tab = kzalloc(new_size * sizeof (void *), GFP_KERNEL);
+ new_tab = vzalloc(new_size * sizeof(void *));
+ if (new_tab == NULL)
+ return -ENOMEM;
for (i = 0; i < size; i++) {
for (bucket = hash->dth_tab[i]; bucket != NULL;
}
}
- kfree(hash->dth_tab);
+ vfree(hash->dth_tab);
hash->dth_tab = new_tab;
hash->dth_size = new_size;
hash->dth_mask = new_mask;
+
+ return 0;
}
-void dtrace_hash_add(dtrace_hash_t *hash, dtrace_probe_t *new)
+int dtrace_hash_add(dtrace_hash_t *hash, dtrace_probe_t *new)
{
int hashval = DTRACE_HASHSTR(hash, new);
int ndx = hashval & hash->dth_mask;
}
if ((hash->dth_nbuckets >> 1) > hash->dth_size) {
- dtrace_hash_resize(hash);
+ int err = 0;
+
+ if ((err = dtrace_hash_resize(hash)) != 0)
+ return err;
+
dtrace_hash_add(hash, new);
return;
}
- bucket = kzalloc(sizeof (dtrace_hashbucket_t), GFP_KERNEL);
+ bucket = vzalloc(sizeof(dtrace_hashbucket_t));
+ if (bucket == NULL)
+ return -ENOMEM;
+
bucket->dthb_next = hash->dth_tab[ndx];
hash->dth_tab[ndx] = bucket;
hash->dth_nbuckets++;
ASSERT(hash->dth_nbuckets > 0);
hash->dth_nbuckets--;
- kfree(bucket);
+ vfree(bucket);
return;
}
ASSERT(MUTEX_HELD(&dtrace_lock));
ASSERT(dp->dtdo_refcnt != 0);
- pred = kzalloc(sizeof (dtrace_predicate_t), GFP_KERNEL);
+ pred = vzalloc(sizeof (dtrace_predicate_t));
+ if (pred == NULL)
+ return NULL;
+
pred->dtp_difo = dp;
pred->dtp_refcnt = 1;
if (--pred->dtp_refcnt == 0) {
dtrace_difo_release(dp, vstate);
- kfree(pred);
+ vfree(pred);
}
}
return -EINVAL;
}
- provider = kzalloc(sizeof (dtrace_provider_t), GFP_KERNEL);
+ provider = vzalloc(sizeof (dtrace_provider_t));
+ if (provider == NULL)
+ return -ENOMEM;
provider->dtpv_name = dtrace_strdup(name);
+ if (provider->dtpv_name == NULL) {
+ vfree(provider);
+ return -ENOMEM;
+ }
provider->dtpv_attr = *pap;
provider->dtpv_priv.dtpp_flags = priv;
}
kfree(old->dtpv_name);
- kfree(old);
+ vfree(old);
return 0;
}
return -EINVAL;
}
- meta = kzalloc(sizeof(dtrace_meta_t), GFP_KERNEL);
+ meta = vzalloc(sizeof(dtrace_meta_t));
+ if (meta == NULL)
+ return -ENOMEM;
meta->dtm_mops = *mops;
- meta->dtm_name = kmalloc(strlen(name) + 1, GFP_KERNEL);
+ meta->dtm_name = vmalloc(strlen(name) + 1);
+ if (meta->dtm_name == NULL) {
+ vfree(meta);
+ return -ENOMEM;
+ }
strcpy(meta->dtm_name, name);
meta->dtm_arg = arg;
mutex_unlock(&dtrace_lock);
mutex_unlock(&dtrace_meta_lock);
- kfree(old->dtm_name);
- kfree(old);
+ vfree(old->dtm_name);
+ vfree(old);
return 0;
}
{
size_t hashsize, maxper, min,
chunksize = dstate->dtds_chunksize;
- void *base;
+ void *base, *percpu;
uintptr_t limit;
dtrace_dynvar_t *dvar, *next, *start;
int i;
if (size < (min = dstate->dtds_chunksize + sizeof (dtrace_dynhash_t)))
size = min;
- if ((base = dtrace_vzalloc_try(size)) == NULL)
+ base = dtrace_vzalloc_try(size);
+ if (base == NULL)
return -ENOMEM;
+ percpu = kmem_cache_alloc(dtrace_state_cache, GFP_KERNEL);
+ if (percpu == NULL) {
+ vfree(base);
+ return -ENOMEM;
+ }
dstate->dtds_size = size;
dstate->dtds_base = base;
- dstate->dtds_percpu = kmem_cache_alloc(dtrace_state_cache, GFP_KERNEL);
+ dstate->dtds_percpu = percpu;
memset(dstate->dtds_percpu, 0,
NR_CPUS * sizeof (dtrace_dstate_percpu_t));
ASSERT((vstate->dtvs_nglobals == 0) ^ (vstate->dtvs_globals != NULL));
if (vstate->dtvs_nglobals > 0)
- kfree(vstate->dtvs_globals);
+ vfree(vstate->dtvs_globals);
if (vstate->dtvs_ntlocals > 0)
- kfree(vstate->dtvs_tlocals);
+ vfree(vstate->dtvs_tlocals);
ASSERT((vstate->dtvs_nlocals == 0) ^ (vstate->dtvs_locals != NULL));
if (vstate->dtvs_nlocals > 0)
- kfree(vstate->dtvs_locals);
+ vfree(vstate->dtvs_locals);
}
static void dtrace_state_clean(dtrace_state_t *state)
dtrace_state_t *state;
dtrace_optval_t *opt;
int bufsize = NR_CPUS * sizeof (dtrace_buffer_t), i;
+#ifdef FIXME
const cred_t *cr = file->f_cred;
+#endif
int err;
dtrace_aggid_t aggid;
ASSERT(MUTEX_HELD(&cpu_lock));
state = kzalloc(sizeof (dtrace_state_t), GFP_KERNEL);
+ if (state == NULL)
+ return NULL;
+
state->dts_epid = DTRACE_EPIDNONE + 1;
- /* state->dts_dev = NULL; -- FIXME: Do we even need this? */
- state->dts_buffer = kzalloc(NR_CPUS * sizeof (dtrace_buffer_t),
- GFP_KERNEL);
- state->dts_buffer = kzalloc(bufsize, GFP_KERNEL);
- state->dts_aggbuffer = kzalloc(bufsize, GFP_KERNEL);
+ state->dts_buffer = vzalloc(bufsize);
+ if (state->dts_buffer == NULL) {
+ vfree(state);
+ return NULL;
+ }
+
+ state->dts_aggbuffer = vzalloc(bufsize);
+ if (state->dts_aggbuffer == NULL) {
+ vfree(state->dts_buffer);
+ vfree(state);
+ return NULL;
+ }
+
idr_init(&state->dts_agg_idr);
state->dts_naggs = 0;
state->dts_cleaner = 0;
}
rval = dtrace_buffer_alloc(buf, size, flags, cpu);
-
if (rval != -ENOMEM) {
opt[which] = size;
return rval;
goto out;
}
- spec = kzalloc(nspec * sizeof(dtrace_speculation_t), GFP_KERNEL);
+ spec = vzalloc(nspec * sizeof(dtrace_speculation_t));
if (spec == NULL) {
rval = -ENOMEM;
goto out;
state->dts_nspeculations = (int)nspec;
for (i = 0; i < nspec; i++) {
- if ((buf = kzalloc(bufsize, GFP_KERNEL)) == NULL) {
+ if ((buf = vzalloc(bufsize)) == NULL) {
rval = -ENOMEM;
goto err;
}
break;
dtrace_buffer_free(buf);
- kfree(buf);
+ vfree(buf);
}
- kfree(spec);
+ vfree(spec);
state->dts_nspeculations = 0;
state->dts_speculations = NULL;
dtrace_dstate_fini(&vstate->dtvs_dynvars);
dtrace_vstate_fini(vstate);
- kfree(state->dts_ecbs);
+ vfree(state->dts_ecbs);
/*
* If there were aggregations allocated, they should have been cleaned
idr_remove_all(&state->dts_agg_idr);
idr_destroy(&state->dts_agg_idr);
- kfree(state->dts_buffer);
- kfree(state->dts_aggbuffer);
+ vfree(state->dts_buffer);
+ vfree(state->dts_aggbuffer);
for (i = 0; i < nspec; i++)
- kfree(spec[i].dtsp_buffer);
+ vfree(spec[i].dtsp_buffer);
- kfree(spec);
+ vfree(spec);
dtrace_format_destroy(state);
}
ntps = dhpb->dthpb_noffs + dhpb->dthpb_nenoffs;
ASSERT(ntps > 0);
- atomic_add(ntps, &fasttrap_total);
+ pp = vzalloc(offsetof(fasttrap_probe_t, ftp_tps[ntps]));
+ if (pp == NULL) {
+ pr_warn("Unable to create probe %s: out-of-memory\n",
+ dhpb->dthpb_name);
+ mutex_unlock(&provider->ftp_cmtx);
+ return;
+ }
+ atomic_add(ntps, &fasttrap_total);
if (atomic_read(&fasttrap_total) > fasttrap_max) {
+ vfree(pp);
atomic_add(-ntps, &fasttrap_total);
mutex_unlock(&provider->ftp_cmtx);
return;
}
- pp = kzalloc(offsetof(fasttrap_probe_t, ftp_tps[ntps]), GFP_KERNEL);
-
pp->ftp_prov = provider;
pp->ftp_pid = provider->ftp_pid;
pp->ftp_ntps = ntps;
* First create a tracepoint for each actual point of interest.
*/
for (i = 0; i < dhpb->dthpb_noffs; i++) {
- tp = kzalloc(sizeof(fasttrap_tracepoint_t), GFP_KERNEL);
+ tp = vzalloc(sizeof(fasttrap_tracepoint_t));
+ if (tp == NULL)
+ goto fail;
tp->ftt_proc = provider->ftp_proc;
tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_offs[i];
* Then create a tracepoint for each is-enabled point.
*/
for (j = 0; i < ntps; i++, j++) {
- tp = kzalloc(sizeof(fasttrap_tracepoint_t), GFP_KERNEL);
+ tp = vzalloc(sizeof(fasttrap_tracepoint_t));
+ if (tp == NULL)
+ goto fail;
tp->ftt_proc = provider->ftp_proc;
tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_enoffs[j];
FASTTRAP_OFFSET_AFRAMES, pp);
mutex_unlock(&provider->ftp_cmtx);
+ return;
+
+fail:
+ pr_warn("Unable to create probe %s: out-of-memory\n",
+ dhpb->dthpb_name);
+
+ for (i = 0; i < ntps; i++)
+ vfree(pp->ftp_tps[i].fit_tp);
+
+ vfree(pp);
+ atomic_add(-ntps, &fasttrap_total);
+ mutex_unlock(&provider->ftp_cmtx);
}
static void fasttrap_proc_release(fasttrap_proc_t *proc)
mutex_unlock(&bucket->ftb_mtx);
- kfree(fprc);
+ vfree(fprc);
}
static void fasttrap_provider_free(fasttrap_provider_t *provider)
fasttrap_proc_release(provider->ftp_proc);
- kfree(provider);
+ vfree(provider);
unregister_pid_provider(pid);
}
*/
mutex_unlock(&bucket->ftb_mtx);
- new_fprc = kzalloc(sizeof(fasttrap_proc_t), GFP_KERNEL);
+ new_fprc = vzalloc(sizeof(fasttrap_proc_t));
+ if (new_fprc == NULL)
+ return NULL;
+
new_fprc->ftpc_pid = pid;
new_fprc->ftpc_rcount = 1;
atomic64_set(&new_fprc->ftpc_acount, 1);
fprc->ftpc_rcount);
mutex_unlock(&fprc->ftpc_mtx);
- kfree(new_fprc);
+ vfree(new_fprc);
return fprc;
}
const dtrace_pattr_t *pa)
{
fasttrap_provider_t *fp, *new_fp = NULL;
+ fasttrap_proc_t *proc;
fasttrap_bucket_t *bucket;
char provname[DTRACE_PROVNAMELEN];
struct task_struct *p;
mutex_unlock(&bucket->ftb_mtx);
if ((p = register_pid_provider(pid)) == NULL)
- return NULL;
+ goto fail;
/*
* Grab the credentials for this process so we have
*/
cred = get_cred(p->cred);
- new_fp = kzalloc(sizeof(fasttrap_provider_t), GFP_KERNEL);
+ if ((proc = fasttrap_proc_lookup(pid)) == NULL)
+ goto fail;
+
+ if ((new_fp = vzalloc(sizeof(fasttrap_provider_t))) == NULL)
+ goto fail;
+
new_fp->ftp_pid = pid;
- new_fp->ftp_proc = fasttrap_proc_lookup(pid);
+ new_fp->ftp_proc = proc;
mutex_init(&new_fp->ftp_mtx);
mutex_init(&new_fp->ftp_cmtx);
put_cred(cred);
return new_fp;
+
+fail:
+ put_cred(cred);
+
+ if (proc)
+ fasttrap_proc_release(proc);
+ if (p)
+ unregister_pid_provider(pid);
+
+ return NULL;
}
void *fasttrap_meta_provide(void *arg, dtrace_helper_provdesc_t *dhpv,
.fops = &fasttrap_fops,
};
-static void fasttrap_init_htable(fasttrap_hash_t *fth, ulong_t nent)
+static int fasttrap_init_htable(fasttrap_hash_t *fth, ulong_t nent)
{
ulong_t i;
ASSERT(fth->fth_nent > 0);
fth->fth_mask = fth->fth_nent - 1;
- fth->fth_table = kzalloc(fth->fth_nent * sizeof(fasttrap_bucket_t),
- GFP_KERNEL);
+ fth->fth_table = vzalloc(fth->fth_nent * sizeof(fasttrap_bucket_t));
+
+ if (fth->fth_table == NULL)
+ return -ENOMEM;
for (i = 0; i < fth->fth_nent; i++)
mutex_init(&fth->fth_table[i].ftb_mtx);
+
+ return 0;
}
int fasttrap_dev_init(void)
if (nent == 0 || nent > 0x1000000)
nent = FASTTRAP_TPOINTS_DEFAULT_SIZE;
- fasttrap_init_htable(&fasttrap_tpoints, nent);
+ if (fasttrap_init_htable(&fasttrap_tpoints, nent) != 0)
+ return -ENOMEM;
/*
* ... and the providers hash table...
*/
nent = FASTTRAP_PROVIDERS_DEFAULT_SIZE;
- fasttrap_init_htable(&fasttrap_provs, nent);
+ if (fasttrap_init_htable(&fasttrap_provs, nent) != 0)
+ return -ENOMEM;
/*
* ... and the procs hash table.
*/
nent = FASTTRAP_PROCS_DEFAULT_SIZE;
- fasttrap_init_htable(&fasttrap_procs, nent);
+ if (fasttrap_init_htable(&fasttrap_procs, nent) != 0)
+ return -ENOMEM;
fail:
return ret;
mutex_unlock(&fasttrap_count_mtx);
#endif
- kfree(fasttrap_tpoints.fth_table);
+ if (fasttrap_tpoints.fth_table)
+ vfree(fasttrap_tpoints.fth_table);
fasttrap_tpoints.fth_nent = 0;
- kfree(fasttrap_provs.fth_table);
+ if (fasttrap_provs.fth_table)
+ vfree(fasttrap_provs.fth_table);
fasttrap_provs.fth_nent = 0;
- kfree(fasttrap_procs.fth_table);
+ if (fasttrap_procs.fth_table)
+ vfree(fasttrap_procs.fth_table);
fasttrap_procs.fth_nent = 0;
/*
*/
extern dtrace_hash_t *dtrace_hash_create(uintptr_t, uintptr_t, uintptr_t);
-extern void dtrace_hash_add(dtrace_hash_t *, dtrace_probe_t *);
+extern int dtrace_hash_add(dtrace_hash_t *, dtrace_probe_t *);
extern dtrace_probe_t *dtrace_hash_lookup(dtrace_hash_t *, dtrace_probe_t *);
extern int dtrace_hash_collisions(dtrace_hash_t *, dtrace_probe_t *);
extern void dtrace_hash_remove(dtrace_hash_t *, dtrace_probe_t *);
if (dtrace_probe_lookup(profile_id, NULL, NULL, name) != 0)
return;
+ prof = vzalloc(sizeof(profile_probe_t));
+ if (prof == NULL) {
+ pr_warn("Unable to create probe %s: out-of-memory\n", name);
+ return;
+ }
+
atomic_inc(&profile_total);
if (atomic_read(&profile_total) > profile_max) {
+ vfree(prof);
atomic_dec(&profile_total);
return;
}
- prof = kzalloc(sizeof(profile_probe_t), GFP_KERNEL);
strcpy(prof->prof_name, name);
prof->prof_interval = interval;
prof->prof_cyclic = CYCLIC_NONE;
profile_probe_t *prof = parg;
ASSERT(prof->prof_cyclic == CYCLIC_NONE);
- kfree(prof);
+ vfree(prof);
ASSERT(atomic_read(&profile_total) >= 1);
atomic_dec(&profile_total);
}
}
- nname = kmalloc(len = strlen(name) + 1, GFP_KERNEL);
+ nname = vmalloc(len = strlen(name) + 1);
+ if (nname == NULL) {
+ pr_warn("Unable to create probe%s: out-of-memory\n",
+ name);
+ continue;
+ }
for (i = j = 0; name[j] != '\0'; i++) {
if (name[j] == '_' && name[j + 1] == '_') {
nname[i] = '\0';
- sdp = kzalloc(sizeof(sdt_probe_t), GFP_KERNEL);
+ sdp = vzalloc(sizeof(sdt_probe_t));
+ if (sdp == NULL) {
+ pr_warn("Unable to create probe %s: out-of-memory\n",
+ nname);
+ continue;
+ }
+
sdp->sdp_loadcnt = 1; /* FIXME */
sdp->sdp_module = mp;
sdp->sdp_name = nname;
else
sdt_probetab[ndx] = sdp->sdp_hashnext;
- kfree(sdp->sdp_name);
+ vfree(sdp->sdp_name);
sdp = sdp->sdp_next;
- kfree(old);
+ vfree(old);
}
}
int ret = 0;
ret = misc_register(&sdt_dev);
- if (ret)
+ if (ret) {
pr_err("%s: Can't register misc device %d\n",
sdt_dev.name, sdt_dev.minor);
+ return ret;
+ }
if (sdt_probetab_size == 0)
sdt_probetab_size = SDT_PROBETAB_SIZE;
sdt_probetab_mask = sdt_probetab_size - 1;
sdt_probetab = vzalloc(sdt_probetab_size * sizeof(sdt_probe_t *));
+ if (sdt_probetab == NULL)
+ return -ENOMEM;
- dtrace_invop_add(sdt_invop);
+ ret = dtrace_invop_add(sdt_invop);
return ret;
}