Revert r212370, as it causes a LOR on powerpc. powerpc does a few
unexpected things in copyout(9) and so wiring the user buffer is not sufficient to perform a copyout(9) while holding a random mutex. Requested by: nwhitehorn
This commit is contained in:
parent
cbb9ebd738
commit
404a593e28
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=212572
@ -3227,6 +3227,7 @@ t3_dump_rspq(SYSCTL_HANDLER_ARGS)
|
||||
struct sge_rspq *rspq;
|
||||
struct sge_qset *qs;
|
||||
int i, err, dump_end, idx;
|
||||
static int multiplier = 1;
|
||||
struct sbuf *sb;
|
||||
struct rsp_desc *rspd;
|
||||
uint32_t data[4];
|
||||
@ -3251,8 +3252,8 @@ t3_dump_rspq(SYSCTL_HANDLER_ARGS)
|
||||
err = t3_sge_read_rspq(qs->port->adapter, rspq->cntxt_id, data);
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
sb = sbuf_new_for_sysctl(NULL, NULL, QDUMP_SBUF_SIZE, req);
|
||||
retry_sbufops:
|
||||
sb = sbuf_new(NULL, NULL, QDUMP_SBUF_SIZE*multiplier, SBUF_FIXEDLEN);
|
||||
|
||||
sbuf_printf(sb, " \n index=%u size=%u MSI-X/RspQ=%u intr enable=%u intr armed=%u\n",
|
||||
(data[0] & 0xffff), data[0] >> 16, ((data[2] >> 20) & 0x3f),
|
||||
@ -3275,11 +3276,13 @@ t3_dump_rspq(SYSCTL_HANDLER_ARGS)
|
||||
rspd->rss_hdr.rss_hash_val, be32toh(rspd->flags),
|
||||
be32toh(rspd->len_cq), rspd->intr_gen);
|
||||
}
|
||||
|
||||
err = sbuf_finish(sb);
|
||||
/* Output a trailing NUL. */
|
||||
if (err == 0)
|
||||
err = SYSCTL_OUT(req, "", 1);
|
||||
if (sbuf_error(sb) != 0) {
|
||||
sbuf_delete(sb);
|
||||
multiplier++;
|
||||
goto retry_sbufops;
|
||||
}
|
||||
sbuf_finish(sb);
|
||||
err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
|
||||
sbuf_delete(sb);
|
||||
return (err);
|
||||
}
|
||||
@ -3290,6 +3293,7 @@ t3_dump_txq_eth(SYSCTL_HANDLER_ARGS)
|
||||
struct sge_txq *txq;
|
||||
struct sge_qset *qs;
|
||||
int i, j, err, dump_end;
|
||||
static int multiplier = 1;
|
||||
struct sbuf *sb;
|
||||
struct tx_desc *txd;
|
||||
uint32_t *WR, wr_hi, wr_lo, gen;
|
||||
@ -3317,7 +3321,9 @@ t3_dump_txq_eth(SYSCTL_HANDLER_ARGS)
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
sb = sbuf_new_for_sysctl(NULL, NULL, QDUMP_SBUF_SIZE, req);
|
||||
|
||||
retry_sbufops:
|
||||
sb = sbuf_new(NULL, NULL, QDUMP_SBUF_SIZE*multiplier, SBUF_FIXEDLEN);
|
||||
|
||||
sbuf_printf(sb, " \n credits=%u GTS=%u index=%u size=%u rspq#=%u cmdq#=%u\n",
|
||||
(data[0] & 0x7fff), ((data[0] >> 15) & 1), (data[0] >> 16),
|
||||
@ -3344,10 +3350,13 @@ t3_dump_txq_eth(SYSCTL_HANDLER_ARGS)
|
||||
WR[j], WR[j + 1], WR[j + 2], WR[j + 3]);
|
||||
|
||||
}
|
||||
err = sbuf_finish(sb);
|
||||
/* Output a trailing NUL. */
|
||||
if (err == 0)
|
||||
err = SYSCTL_OUT(req, "", 1);
|
||||
if (sbuf_error(sb) != 0) {
|
||||
sbuf_delete(sb);
|
||||
multiplier++;
|
||||
goto retry_sbufops;
|
||||
}
|
||||
sbuf_finish(sb);
|
||||
err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
|
||||
sbuf_delete(sb);
|
||||
return (err);
|
||||
}
|
||||
@ -3358,6 +3367,7 @@ t3_dump_txq_ctrl(SYSCTL_HANDLER_ARGS)
|
||||
struct sge_txq *txq;
|
||||
struct sge_qset *qs;
|
||||
int i, j, err, dump_end;
|
||||
static int multiplier = 1;
|
||||
struct sbuf *sb;
|
||||
struct tx_desc *txd;
|
||||
uint32_t *WR, wr_hi, wr_lo, gen;
|
||||
@ -3381,7 +3391,8 @@ t3_dump_txq_ctrl(SYSCTL_HANDLER_ARGS)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
sb = sbuf_new_for_sysctl(NULL, NULL, QDUMP_SBUF_SIZE, req);
|
||||
retry_sbufops:
|
||||
sb = sbuf_new(NULL, NULL, QDUMP_SBUF_SIZE*multiplier, SBUF_FIXEDLEN);
|
||||
sbuf_printf(sb, " qid=%d start=%d -> end=%d\n", qs->idx,
|
||||
txq->txq_dump_start,
|
||||
(txq->txq_dump_start + txq->txq_dump_count) & 255);
|
||||
@ -3401,10 +3412,13 @@ t3_dump_txq_ctrl(SYSCTL_HANDLER_ARGS)
|
||||
WR[j], WR[j + 1], WR[j + 2], WR[j + 3]);
|
||||
|
||||
}
|
||||
err = sbuf_finish(sb);
|
||||
/* Output a trailing NUL. */
|
||||
if (err == 0)
|
||||
err = SYSCTL_OUT(req, "", 1);
|
||||
if (sbuf_error(sb) != 0) {
|
||||
sbuf_delete(sb);
|
||||
multiplier++;
|
||||
goto retry_sbufops;
|
||||
}
|
||||
sbuf_finish(sb);
|
||||
err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
|
||||
sbuf_delete(sb);
|
||||
return (err);
|
||||
}
|
||||
|
@ -828,11 +828,25 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS)
|
||||
struct malloc_type_internal *mtip;
|
||||
struct malloc_type_header mth;
|
||||
struct malloc_type *mtp;
|
||||
int error, i;
|
||||
int buflen, count, error, i;
|
||||
struct sbuf sbuf;
|
||||
char *buffer;
|
||||
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
mtx_lock(&malloc_mtx);
|
||||
restart:
|
||||
mtx_assert(&malloc_mtx, MA_OWNED);
|
||||
count = kmemcount;
|
||||
mtx_unlock(&malloc_mtx);
|
||||
buflen = sizeof(mtsh) + count * (sizeof(mth) +
|
||||
sizeof(struct malloc_type_stats) * MAXCPU) + 1;
|
||||
buffer = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
|
||||
mtx_lock(&malloc_mtx);
|
||||
if (count < kmemcount) {
|
||||
free(buffer, M_TEMP);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
sbuf_new(&sbuf, buffer, buflen, SBUF_FIXEDLEN);
|
||||
|
||||
/*
|
||||
* Insert stream header.
|
||||
@ -841,7 +855,11 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS)
|
||||
mtsh.mtsh_version = MALLOC_TYPE_STREAM_VERSION;
|
||||
mtsh.mtsh_maxcpus = MAXCPU;
|
||||
mtsh.mtsh_count = kmemcount;
|
||||
(void)sbuf_bcat(&sbuf, &mtsh, sizeof(mtsh));
|
||||
if (sbuf_bcat(&sbuf, &mtsh, sizeof(mtsh)) < 0) {
|
||||
mtx_unlock(&malloc_mtx);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert alternating sequence of type headers and type statistics.
|
||||
@ -854,19 +872,30 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS)
|
||||
*/
|
||||
bzero(&mth, sizeof(mth));
|
||||
strlcpy(mth.mth_name, mtp->ks_shortdesc, MALLOC_MAX_NAME);
|
||||
(void)sbuf_bcat(&sbuf, &mth, sizeof(mth));
|
||||
if (sbuf_bcat(&sbuf, &mth, sizeof(mth)) < 0) {
|
||||
mtx_unlock(&malloc_mtx);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert type statistics for each CPU.
|
||||
*/
|
||||
for (i = 0; i < MAXCPU; i++) {
|
||||
(void)sbuf_bcat(&sbuf, &mtip->mti_stats[i],
|
||||
sizeof(mtip->mti_stats[i]));
|
||||
if (sbuf_bcat(&sbuf, &mtip->mti_stats[i],
|
||||
sizeof(mtip->mti_stats[i])) < 0) {
|
||||
mtx_unlock(&malloc_mtx);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
mtx_unlock(&malloc_mtx);
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_finish(&sbuf);
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
|
||||
out:
|
||||
sbuf_delete(&sbuf);
|
||||
free(buffer, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -976,19 +1005,26 @@ DB_SHOW_COMMAND(multizone_matches, db_show_multizone_matches)
|
||||
static int
|
||||
sysctl_kern_mprof(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int linesize = 64;
|
||||
struct sbuf sbuf;
|
||||
uint64_t count;
|
||||
uint64_t waste;
|
||||
uint64_t mem;
|
||||
int bufsize;
|
||||
int error;
|
||||
char *buf;
|
||||
int rsize;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
bufsize = linesize * (KMEM_ZSIZE + 1);
|
||||
bufsize += 128; /* For the stats line */
|
||||
bufsize += 128; /* For the banner line */
|
||||
waste = 0;
|
||||
mem = 0;
|
||||
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
buf = malloc(bufsize, M_TEMP, M_WAITOK|M_ZERO);
|
||||
sbuf_new(&sbuf, buf, bufsize, SBUF_FIXEDLEN);
|
||||
sbuf_printf(&sbuf,
|
||||
"\n Size Requests Real Size\n");
|
||||
for (i = 0; i < KMEM_ZSIZE; i++) {
|
||||
@ -1006,8 +1042,12 @@ sysctl_kern_mprof(SYSCTL_HANDLER_ARGS)
|
||||
sbuf_printf(&sbuf,
|
||||
"\nTotal memory used:\t%30llu\nTotal Memory wasted:\t%30llu\n",
|
||||
(unsigned long long)mem, (unsigned long long)waste);
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_finish(&sbuf);
|
||||
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
|
||||
|
||||
sbuf_delete(&sbuf);
|
||||
free(buf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/jail.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/uio.h>
|
||||
@ -1545,30 +1544,3 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drain into a sysctl struct. The user buffer must be wired.
|
||||
*/
|
||||
static int
|
||||
sbuf_sysctl_drain(void *arg, const char *data, int len)
|
||||
{
|
||||
struct sysctl_req *req = arg;
|
||||
int error;
|
||||
|
||||
error = SYSCTL_OUT(req, data, len);
|
||||
KASSERT(error >= 0, ("Got unexpected negative value %d", error));
|
||||
return (error == 0 ? len : -error);
|
||||
}
|
||||
|
||||
struct sbuf *
|
||||
sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length,
|
||||
struct sysctl_req *req)
|
||||
{
|
||||
|
||||
/* Wire the user buffer, so we can write without blocking. */
|
||||
sysctl_wire_old_buffer(req, 0);
|
||||
|
||||
s = sbuf_new(s, buf, length, SBUF_FIXEDLEN);
|
||||
sbuf_set_drain(s, sbuf_sysctl_drain, req);
|
||||
return (s);
|
||||
}
|
||||
|
@ -191,7 +191,8 @@ struct lock_prof_cpu *lp_cpu[MAXCPU];
|
||||
volatile int lock_prof_enable = 0;
|
||||
static volatile int lock_prof_resetting;
|
||||
|
||||
#define LPROF_SBUF_SIZE 256
|
||||
/* SWAG: sbuf size = avg stat. line size * number of locks */
|
||||
#define LPROF_SBUF_SIZE 256 * 400
|
||||
|
||||
static int lock_prof_rejected;
|
||||
static int lock_prof_skipspin;
|
||||
@ -383,6 +384,8 @@ lock_prof_type_stats(struct lock_prof_type *type, struct sbuf *sb, int spin,
|
||||
continue;
|
||||
lock_prof_sum(l, &lp, i, spin, t);
|
||||
lock_prof_output(&lp, sb);
|
||||
if (sbuf_error(sb) != 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -390,11 +393,13 @@ lock_prof_type_stats(struct lock_prof_type *type, struct sbuf *sb, int spin,
|
||||
static int
|
||||
dump_lock_prof_stats(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
static int multiplier = 1;
|
||||
struct sbuf *sb;
|
||||
int error, cpu, t;
|
||||
int enabled;
|
||||
|
||||
sb = sbuf_new_for_sysctl(NULL, NULL, LPROF_SBUF_SIZE, req);
|
||||
retry_sbufops:
|
||||
sb = sbuf_new(NULL, NULL, LPROF_SBUF_SIZE * multiplier, SBUF_FIXEDLEN);
|
||||
sbuf_printf(sb, "\n%8s %9s %11s %11s %11s %6s %6s %2s %6s %s\n",
|
||||
"max", "wait_max", "total", "wait_total", "count", "avg", "wait_avg", "cnt_hold", "cnt_lock", "name");
|
||||
enabled = lock_prof_enable;
|
||||
@ -406,13 +411,16 @@ dump_lock_prof_stats(SYSCTL_HANDLER_ARGS)
|
||||
continue;
|
||||
lock_prof_type_stats(&lp_cpu[cpu]->lpc_types[0], sb, 0, t);
|
||||
lock_prof_type_stats(&lp_cpu[cpu]->lpc_types[1], sb, 1, t);
|
||||
if (sbuf_error(sb) != 0) {
|
||||
sbuf_delete(sb);
|
||||
multiplier++;
|
||||
goto retry_sbufops;
|
||||
}
|
||||
}
|
||||
lock_prof_enable = enabled;
|
||||
|
||||
error = sbuf_finish(sb);
|
||||
/* Output a trailing NUL. */
|
||||
if (error == 0)
|
||||
error = SYSCTL_OUT(req, "", 1);
|
||||
sbuf_finish(sb);
|
||||
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
|
||||
sbuf_delete(sb);
|
||||
return (error);
|
||||
}
|
||||
|
@ -303,8 +303,8 @@ sbuf_drain(struct sbuf *s)
|
||||
s->s_error = -len;
|
||||
return (s->s_error);
|
||||
}
|
||||
KASSERT(len > 0 && len <= s->s_len,
|
||||
("Bad drain amount %d for sbuf %p", len, s));
|
||||
|
||||
KASSERT(len > 0, ("Drain must either error or work!"));
|
||||
s->s_len -= len;
|
||||
/*
|
||||
* Fast path for the expected case where all the data was
|
||||
|
@ -1018,7 +1018,7 @@ sleepq_abort(struct thread *td, int intrval)
|
||||
|
||||
#ifdef SLEEPQUEUE_PROFILING
|
||||
#define SLEEPQ_PROF_LOCATIONS 1024
|
||||
#define SLEEPQ_SBUFSIZE 512
|
||||
#define SLEEPQ_SBUFSIZE (40 * 512)
|
||||
struct sleepq_prof {
|
||||
LIST_ENTRY(sleepq_prof) sp_link;
|
||||
const char *sp_wmesg;
|
||||
@ -1123,13 +1123,15 @@ reset_sleepq_prof_stats(SYSCTL_HANDLER_ARGS)
|
||||
static int
|
||||
dump_sleepq_prof_stats(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
static int multiplier = 1;
|
||||
struct sleepq_prof *sp;
|
||||
struct sbuf *sb;
|
||||
int enabled;
|
||||
int error;
|
||||
int i;
|
||||
|
||||
sb = sbuf_new_for_sysctl(NULL, NULL, SLEEPQ_SBUFSIZE, req);
|
||||
retry_sbufops:
|
||||
sb = sbuf_new(NULL, NULL, SLEEPQ_SBUFSIZE * multiplier, SBUF_FIXEDLEN);
|
||||
sbuf_printf(sb, "\nwmesg\tcount\n");
|
||||
enabled = prof_enabled;
|
||||
mtx_lock_spin(&sleepq_prof_lock);
|
||||
@ -1139,13 +1141,19 @@ dump_sleepq_prof_stats(SYSCTL_HANDLER_ARGS)
|
||||
LIST_FOREACH(sp, &sleepq_hash[i], sp_link) {
|
||||
sbuf_printf(sb, "%s\t%ld\n",
|
||||
sp->sp_wmesg, sp->sp_count);
|
||||
if (sbuf_error(sb) != 0) {
|
||||
sbuf_delete(sb);
|
||||
multiplier++;
|
||||
goto retry_sbufops;
|
||||
}
|
||||
}
|
||||
}
|
||||
mtx_lock_spin(&sleepq_prof_lock);
|
||||
prof_enabled = enabled;
|
||||
mtx_unlock_spin(&sleepq_prof_lock);
|
||||
|
||||
error = sbuf_finish(sb);
|
||||
sbuf_finish(sb);
|
||||
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
|
||||
sbuf_delete(sb);
|
||||
return (error);
|
||||
}
|
||||
|
@ -154,7 +154,8 @@ __FBSDID("$FreeBSD$");
|
||||
#define MAX_W_NAME 64
|
||||
|
||||
#define BADSTACK_SBUF_SIZE (256 * WITNESS_COUNT)
|
||||
#define FULLGRAPH_SBUF_SIZE 512
|
||||
#define CYCLEGRAPH_SBUF_SIZE 8192
|
||||
#define FULLGRAPH_SBUF_SIZE 32768
|
||||
|
||||
/*
|
||||
* These flags go in the witness relationship matrix and describe the
|
||||
@ -2544,7 +2545,7 @@ sysctl_debug_witness_fullgraph(SYSCTL_HANDLER_ARGS)
|
||||
return (error);
|
||||
}
|
||||
error = 0;
|
||||
sb = sbuf_new_for_sysctl(NULL, NULL, FULLGRAPH_SBUF_SIZE, req);
|
||||
sb = sbuf_new(NULL, NULL, FULLGRAPH_SBUF_SIZE, SBUF_FIXEDLEN);
|
||||
if (sb == NULL)
|
||||
return (ENOMEM);
|
||||
sbuf_printf(sb, "\n");
|
||||
@ -2556,10 +2557,20 @@ sysctl_debug_witness_fullgraph(SYSCTL_HANDLER_ARGS)
|
||||
witness_add_fullgraph(sb, w);
|
||||
mtx_unlock_spin(&w_mtx);
|
||||
|
||||
/*
|
||||
* While using SBUF_FIXEDLEN, check if the sbuf overflowed.
|
||||
*/
|
||||
if (sbuf_error(sb) != 0) {
|
||||
sbuf_delete(sb);
|
||||
panic("%s: sbuf overflowed, bump FULLGRAPH_SBUF_SIZE value\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the sbuf and return to userland.
|
||||
*/
|
||||
error = sbuf_finish(sb);
|
||||
sbuf_finish(sb);
|
||||
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
|
||||
sbuf_delete(sb);
|
||||
|
||||
return (error);
|
||||
|
@ -710,9 +710,6 @@ void sysctl_lock(void);
|
||||
void sysctl_unlock(void);
|
||||
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len);
|
||||
|
||||
struct sbuf;
|
||||
struct sbuf *sbuf_new_for_sysctl(struct sbuf *, char *, int,
|
||||
struct sysctl_req *);
|
||||
#else /* !_KERNEL */
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
|
@ -3175,16 +3175,36 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
|
||||
uma_keg_t kz;
|
||||
uma_zone_t z;
|
||||
uma_keg_t k;
|
||||
int count, error, i;
|
||||
char *buffer;
|
||||
int buflen, count, error, i;
|
||||
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
|
||||
count = 0;
|
||||
mtx_lock(&uma_mtx);
|
||||
restart:
|
||||
mtx_assert(&uma_mtx, MA_OWNED);
|
||||
count = 0;
|
||||
LIST_FOREACH(kz, &uma_kegs, uk_link) {
|
||||
LIST_FOREACH(z, &kz->uk_zones, uz_link)
|
||||
count++;
|
||||
}
|
||||
mtx_unlock(&uma_mtx);
|
||||
|
||||
buflen = sizeof(ush) + count * (sizeof(uth) + sizeof(ups) *
|
||||
(mp_maxid + 1)) + 1;
|
||||
buffer = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
|
||||
|
||||
mtx_lock(&uma_mtx);
|
||||
i = 0;
|
||||
LIST_FOREACH(kz, &uma_kegs, uk_link) {
|
||||
LIST_FOREACH(z, &kz->uk_zones, uz_link)
|
||||
i++;
|
||||
}
|
||||
if (i > count) {
|
||||
free(buffer, M_TEMP);
|
||||
goto restart;
|
||||
}
|
||||
count = i;
|
||||
|
||||
sbuf_new(&sbuf, buffer, buflen, SBUF_FIXEDLEN);
|
||||
|
||||
/*
|
||||
* Insert stream header.
|
||||
@ -3193,7 +3213,11 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
|
||||
ush.ush_version = UMA_STREAM_VERSION;
|
||||
ush.ush_maxcpus = (mp_maxid + 1);
|
||||
ush.ush_count = count;
|
||||
(void)sbuf_bcat(&sbuf, &ush, sizeof(ush));
|
||||
if (sbuf_bcat(&sbuf, &ush, sizeof(ush)) < 0) {
|
||||
mtx_unlock(&uma_mtx);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
LIST_FOREACH(kz, &uma_kegs, uk_link) {
|
||||
LIST_FOREACH(z, &kz->uk_zones, uz_link) {
|
||||
@ -3226,7 +3250,12 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
|
||||
uth.uth_frees = z->uz_frees;
|
||||
uth.uth_fails = z->uz_fails;
|
||||
uth.uth_sleeps = z->uz_sleeps;
|
||||
(void)sbuf_bcat(&sbuf, &uth, sizeof(uth));
|
||||
if (sbuf_bcat(&sbuf, &uth, sizeof(uth)) < 0) {
|
||||
ZONE_UNLOCK(z);
|
||||
mtx_unlock(&uma_mtx);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* While it is not normally safe to access the cache
|
||||
* bucket pointers while not on the CPU that owns the
|
||||
@ -3251,14 +3280,21 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
|
||||
ups.ups_allocs = cache->uc_allocs;
|
||||
ups.ups_frees = cache->uc_frees;
|
||||
skip:
|
||||
(void)sbuf_bcat(&sbuf, &ups, sizeof(ups));
|
||||
if (sbuf_bcat(&sbuf, &ups, sizeof(ups)) < 0) {
|
||||
ZONE_UNLOCK(z);
|
||||
mtx_unlock(&uma_mtx);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ZONE_UNLOCK(z);
|
||||
}
|
||||
}
|
||||
mtx_unlock(&uma_mtx);
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_delete(&sbuf);
|
||||
sbuf_finish(&sbuf);
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
|
||||
out:
|
||||
free(buffer, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -123,9 +123,12 @@ sysctl_vm_phys_free(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct sbuf sbuf;
|
||||
struct vm_freelist *fl;
|
||||
char *cbuf;
|
||||
const int cbufsize = vm_nfreelists*(VM_NFREEORDER + 1)*81;
|
||||
int error, flind, oind, pind;
|
||||
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
cbuf = malloc(cbufsize, M_TEMP, M_WAITOK | M_ZERO);
|
||||
sbuf_new(&sbuf, cbuf, cbufsize, SBUF_FIXEDLEN);
|
||||
for (flind = 0; flind < vm_nfreelists; flind++) {
|
||||
sbuf_printf(&sbuf, "\nFREE LIST %d:\n"
|
||||
"\n ORDER (SIZE) | NUMBER"
|
||||
@ -146,8 +149,10 @@ sysctl_vm_phys_free(SYSCTL_HANDLER_ARGS)
|
||||
sbuf_printf(&sbuf, "\n");
|
||||
}
|
||||
}
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_finish(&sbuf);
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
|
||||
sbuf_delete(&sbuf);
|
||||
free(cbuf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -159,9 +164,12 @@ sysctl_vm_phys_segs(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct sbuf sbuf;
|
||||
struct vm_phys_seg *seg;
|
||||
char *cbuf;
|
||||
const int cbufsize = VM_PHYSSEG_MAX*(VM_NFREEORDER + 1)*81;
|
||||
int error, segind;
|
||||
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
cbuf = malloc(cbufsize, M_TEMP, M_WAITOK | M_ZERO);
|
||||
sbuf_new(&sbuf, cbuf, cbufsize, SBUF_FIXEDLEN);
|
||||
for (segind = 0; segind < vm_phys_nsegs; segind++) {
|
||||
sbuf_printf(&sbuf, "\nSEGMENT %d:\n\n", segind);
|
||||
seg = &vm_phys_segs[segind];
|
||||
@ -172,8 +180,10 @@ sysctl_vm_phys_segs(SYSCTL_HANDLER_ARGS)
|
||||
sbuf_printf(&sbuf, "domain: %d\n", seg->domain);
|
||||
sbuf_printf(&sbuf, "free list: %p\n", seg->free_queues);
|
||||
}
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_finish(&sbuf);
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
|
||||
sbuf_delete(&sbuf);
|
||||
free(cbuf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -185,18 +195,23 @@ static int
|
||||
sysctl_vm_phys_lookup_lists(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct sbuf sbuf;
|
||||
char *cbuf;
|
||||
const int cbufsize = (vm_nfreelists + 1) * VM_NDOMAIN * 81;
|
||||
int domain, error, flind, ndomains;
|
||||
|
||||
ndomains = vm_nfreelists - VM_NFREELIST + 1;
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
cbuf = malloc(cbufsize, M_TEMP, M_WAITOK | M_ZERO);
|
||||
sbuf_new(&sbuf, cbuf, cbufsize, SBUF_FIXEDLEN);
|
||||
for (domain = 0; domain < ndomains; domain++) {
|
||||
sbuf_printf(&sbuf, "\nDOMAIN %d:\n\n", domain);
|
||||
for (flind = 0; flind < vm_nfreelists; flind++)
|
||||
sbuf_printf(&sbuf, " [%d]:\t%p\n", flind,
|
||||
vm_phys_lookup_lists[domain][flind]);
|
||||
}
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_finish(&sbuf);
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
|
||||
sbuf_delete(&sbuf);
|
||||
free(cbuf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
|
@ -180,9 +180,12 @@ sysctl_vm_reserv_partpopq(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct sbuf sbuf;
|
||||
vm_reserv_t rv;
|
||||
char *cbuf;
|
||||
const int cbufsize = (VM_NRESERVLEVEL + 1) * 81;
|
||||
int counter, error, level, unused_pages;
|
||||
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
cbuf = malloc(cbufsize, M_TEMP, M_WAITOK | M_ZERO);
|
||||
sbuf_new(&sbuf, cbuf, cbufsize, SBUF_FIXEDLEN);
|
||||
sbuf_printf(&sbuf, "\nLEVEL SIZE NUMBER\n\n");
|
||||
for (level = -1; level <= VM_NRESERVLEVEL - 2; level++) {
|
||||
counter = 0;
|
||||
@ -196,8 +199,10 @@ sysctl_vm_reserv_partpopq(SYSCTL_HANDLER_ARGS)
|
||||
sbuf_printf(&sbuf, "%5.5d: %6.6dK, %6.6d\n", level,
|
||||
unused_pages * (PAGE_SIZE / 1024), counter);
|
||||
}
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_finish(&sbuf);
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
|
||||
sbuf_delete(&sbuf);
|
||||
free(cbuf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user