Date: Mon, 13 Sep 2010 18:48:23 +0000 (UTC) From: Matthew D Fleming <mdf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r212572 - in head/sys: dev/cxgb kern sys vm Message-ID: <201009131848.o8DImNU6024992@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mdf Date: Mon Sep 13 18:48:23 2010 New Revision: 212572 URL: http://svn.freebsd.org/changeset/base/212572 Log: 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 Modified: head/sys/dev/cxgb/cxgb_sge.c head/sys/kern/kern_malloc.c head/sys/kern/kern_sysctl.c head/sys/kern/subr_lock.c head/sys/kern/subr_sbuf.c head/sys/kern/subr_sleepqueue.c head/sys/kern/subr_witness.c head/sys/sys/sysctl.h head/sys/vm/uma_core.c head/sys/vm/vm_phys.c head/sys/vm/vm_reserv.c Modified: head/sys/dev/cxgb/cxgb_sge.c ============================================================================== --- head/sys/dev/cxgb/cxgb_sge.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/dev/cxgb/cxgb_sge.c Mon Sep 13 18:48:23 2010 (r212572) @@ -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); } Modified: head/sys/kern/kern_malloc.c ============================================================================== --- head/sys/kern/kern_malloc.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/kern/kern_malloc.c Mon Sep 13 18:48:23 2010 (r212572) @@ -828,11 +828,25 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ 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_ 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_ */ 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_sh 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); } Modified: head/sys/kern/kern_sysctl.c ============================================================================== --- head/sys/kern/kern_sysctl.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/kern/kern_sysctl.c Mon Sep 13 18:48:23 2010 (r212572) @@ -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 * } 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); -} Modified: head/sys/kern/subr_lock.c ============================================================================== --- head/sys/kern/subr_lock.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/kern/subr_lock.c Mon Sep 13 18:48:23 2010 (r212572) @@ -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_ty 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_ty 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); } Modified: head/sys/kern/subr_sbuf.c ============================================================================== --- head/sys/kern/subr_sbuf.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/kern/subr_sbuf.c Mon Sep 13 18:48:23 2010 (r212572) @@ -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 Modified: head/sys/kern/subr_sleepqueue.c ============================================================================== --- head/sys/kern/subr_sleepqueue.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/kern/subr_sleepqueue.c Mon Sep 13 18:48:23 2010 (r212572) @@ -1018,7 +1018,7 @@ sleepq_abort(struct thread *td, int intr #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_A 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_AR 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); } Modified: head/sys/kern/subr_witness.c ============================================================================== --- head/sys/kern/subr_witness.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/kern/subr_witness.c Mon Sep 13 18:48:23 2010 (r212572) @@ -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_HA 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"); @@ -2557,9 +2558,19 @@ sysctl_debug_witness_fullgraph(SYSCTL_HA 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); Modified: head/sys/sys/sysctl.h ============================================================================== --- head/sys/sys/sysctl.h Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/sys/sysctl.h Mon Sep 13 18:48:23 2010 (r212572) @@ -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> Modified: head/sys/vm/uma_core.c ============================================================================== --- head/sys/vm/uma_core.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/vm/uma_core.c Mon Sep 13 18:48:23 2010 (r212572) @@ -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); } Modified: head/sys/vm/vm_phys.c ============================================================================== --- head/sys/vm/vm_phys.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/vm/vm_phys.c Mon Sep 13 18:48:23 2010 (r212572) @@ -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 Modified: head/sys/vm/vm_reserv.c ============================================================================== --- head/sys/vm/vm_reserv.c Mon Sep 13 18:32:49 2010 (r212571) +++ head/sys/vm/vm_reserv.c Mon Sep 13 18:48:23 2010 (r212572) @@ -180,9 +180,12 @@ sysctl_vm_reserv_partpopq(SYSCTL_HANDLER { 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 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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009131848.o8DImNU6024992>