svn commit: r248722 - head/sys/geom
Author: mav Date: Tue Mar 26 07:55:24 2013 New Revision: 248722 URL: http://svnweb.freebsd.org/changeset/base/248722 Log: geom_slice.c and its consumers like GEOM_LABEL are not touching the data unless hotspots are used. Pass G_PF_ACCEPT_UNMAPPED flag through except such rare cases (obsolete GEOM_SUNLABEL and GEOM_BSD). Modified: head/sys/geom/geom_slice.c Modified: head/sys/geom/geom_slice.c == --- head/sys/geom/geom_slice.c Tue Mar 26 05:58:49 2013(r248721) +++ head/sys/geom/geom_slice.c Tue Mar 26 07:55:24 2013(r248722) @@ -396,6 +396,8 @@ g_slice_config(struct g_geom *gp, u_int pp->stripeoffset = pp2->stripeoffset + offset; if (pp->stripesize > 0) pp->stripeoffset %= pp->stripesize; + if (gsp->nhotspot == 0) + pp->flags |= pp2->flags & G_PF_ACCEPT_UNMAPPED; if (0 && bootverbose) printf("GEOM: Configure %s, start %jd length %jd end %jd\n", pp->name, (intmax_t)offset, (intmax_t)length, @@ -428,11 +430,17 @@ g_slice_conf_hot(struct g_geom *gp, u_in { struct g_slicer *gsp; struct g_slice_hot *gsl, *gsl2; + struct g_provider *pp; g_trace(G_T_TOPOLOGY, "g_slice_conf_hot(%s, idx: %d, off: %jd, len: %jd)", gp->name, idx, (intmax_t)offset, (intmax_t)length); g_topology_assert(); gsp = gp->softc; + /* Deny unmapped I/O if hotspots are used. */ + if (gsp->nhotspot == 0) { + LIST_FOREACH(pp, &gp->provider, provider) + pp->flags &= ~G_PF_ACCEPT_UNMAPPED; + } gsl = gsp->hotspot; if(idx >= gsp->nhotspot) { gsl2 = g_malloc((idx + 1) * sizeof *gsl2, M_WAITOK | M_ZERO); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248724 - head/sys/netgraph/netflow
Author: glebius Date: Tue Mar 26 14:05:37 2013 New Revision: 248724 URL: http://svnweb.freebsd.org/changeset/base/248724 Log: Cleanup: wrap long lines, cleanup comments, etc. Modified: head/sys/netgraph/netflow/netflow.c head/sys/netgraph/netflow/ng_netflow.c Modified: head/sys/netgraph/netflow/netflow.c == --- head/sys/netgraph/netflow/netflow.c Tue Mar 26 10:08:54 2013 (r248723) +++ head/sys/netgraph/netflow/netflow.c Tue Mar 26 14:05:37 2013 (r248724) @@ -91,19 +91,19 @@ static const char rcs_id[] = */ #defineSMALL(fle) (fle->f.packets <= 4) - -MALLOC_DECLARE(M_NETFLOW_HASH); MALLOC_DEFINE(M_NETFLOW_HASH, "netflow_hash", "NetFlow hash"); static int export_add(item_p, struct flow_entry *); static int export_send(priv_p, fib_export_p, item_p, int); -static int hash_insert(priv_p, struct flow_hash_entry *, struct flow_rec *, int, uint8_t, uint8_t); +static int hash_insert(priv_p, struct flow_hash_entry *, struct flow_rec *, +int, uint8_t, uint8_t); #ifdef INET6 -static int hash6_insert(priv_p, struct flow_hash_entry *, struct flow6_rec *, int, uint8_t, uint8_t); +static int hash6_insert(priv_p, struct flow_hash_entry *, struct flow6_rec *, +int, uint8_t, uint8_t); #endif -static __inline void expire_flow(priv_p, fib_export_p, struct flow_entry *, int); +static void expire_flow(priv_p, fib_export_p, struct flow_entry *, int); /* * Generate hash for a given flow record. @@ -115,9 +115,10 @@ static __inline void expire_flow(priv_p, * all globally unique (it's not fully true, there is FC00::/7 for example, * but chances of address overlap are MUCH smaller) */ -static __inline uint32_t +static inline uint32_t ip_hash(struct flow_rec *r) { + switch (r->r_ip_p) { case IPPROTO_TCP: case IPPROTO_UDP: @@ -130,9 +131,10 @@ ip_hash(struct flow_rec *r) #ifdef INET6 /* Generate hash for a given flow6 record. Use lower 4 octets from v6 addresses */ -static __inline uint32_t +static inline uint32_t ip6_hash(struct flow6_rec *r) { + switch (r->r_ip_p) { case IPPROTO_TCP: case IPPROTO_UDP: @@ -224,7 +226,6 @@ get_export_dgram(priv_p priv, fib_export dgram->header.count = 0; dgram->header.version = htons(NETFLOW_V5); dgram->header.pad = 0; - } return (item); @@ -236,6 +237,7 @@ get_export_dgram(priv_p priv, fib_export static void return_export_dgram(priv_p priv, fib_export_p fe, item_p item, int flags) { + /* * It may happen on SMP, that some thread has already * put its item there, in this case we bail out and @@ -255,7 +257,7 @@ return_export_dgram(priv_p priv, fib_exp * The flow is over. Call export_add() and free it. If datagram is * full, then call export_send(). */ -static __inline void +static void expire_flow(priv_p priv, fib_export_p fe, struct flow_entry *fle, int flags) { struct netflow_export_item exp; @@ -267,7 +269,7 @@ expire_flow(priv_p priv, fib_export_p fe atomic_add_32(&priv->info.nfinfo_export_failed, 1); if (priv->export9 != NULL) atomic_add_32(&priv->info.nfinfo_export9_failed, 1); - /* fle definitely contains IPv4 flow */ + /* fle definitely contains IPv4 flow. */ uma_zfree_arg(priv->zone, fle, priv); return; } @@ -289,14 +291,16 @@ expire_flow(priv_p priv, fib_export_p fe uma_zfree_arg(priv->zone6, fle, priv); #endif else - panic("ng_netflow: Unknown IP proto: %d", version); + panic("ng_netflow: Unknown IP proto: %d", + version); return; } if (export9_add(exp.item9, exp.item9_opt, fle) > 0) export9_send(priv, fe, exp.item9, exp.item9_opt, flags); else - return_export9_dgram(priv, fe, exp.item9, exp.item9_opt, NG_QUEUE); + return_export9_dgram(priv, fe, exp.item9, + exp.item9_opt, NG_QUEUE); } if (version == IPVERSION) @@ -311,6 +315,7 @@ expire_flow(priv_p priv, fib_export_p fe void ng_netflow_copyinfo(priv_p priv, struct ng_netflow_info *i) { + /* XXX: atomic */ memcpy((void *)i, (void *)&priv->info, sizeof(priv->info)); } @@ -345,7 +350,6 @@ hash_insert(priv_p priv, struct flow_has * Now fle is totally ours. It is detached from all lists, * we can safely edit it. */ - fle->f.version = IPVERSION; bcopy(r, &fle->f.r, sizeof(struct flow_rec)); fle->f.bytes = plen; @@ -373,8 +377,8 @@ hash_insert(priv_
svn commit: r248725 - head/sys/netgraph/netflow
Author: glebius Date: Tue Mar 26 14:08:14 2013 New Revision: 248725 URL: http://svnweb.freebsd.org/changeset/base/248725 Log: Return ENOMEM if malloc() fails. Modified: head/sys/netgraph/netflow/netflow.c Modified: head/sys/netgraph/netflow/netflow.c == --- head/sys/netgraph/netflow/netflow.c Tue Mar 26 14:05:37 2013 (r248724) +++ head/sys/netgraph/netflow/netflow.c Tue Mar 26 14:08:14 2013 (r248725) @@ -574,7 +574,7 @@ ng_netflow_fib_init(priv_p priv, int fib if ((fe = malloc(sizeof(struct fib_export), M_NETGRAPH, M_NOWAIT | M_ZERO)) == NULL) - return (1); + return (ENOMEM); mtx_init(&fe->export_mtx, "export dgram lock", NULL, MTX_DEF); mtx_init(&fe->export9_mtx, "export9 dgram lock", NULL, MTX_DEF); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248728 - head/sys/vm
Author: alc Date: Tue Mar 26 17:30:40 2013 New Revision: 248728 URL: http://svnweb.freebsd.org/changeset/base/248728 Log: Introduce vm_radix_isleaf() and use it in a couple places. As compared to using vm_radix_node_page() == NULL, the compiler is able to generate one less conditional branch when vm_radix_isleaf() is used. More use cases involving the inner loops of vm_radix_insert(), vm_radix_lookup{,_ge,_le}(), and vm_radix_remove() will follow. Reviewed by: attilio Sponsored by: EMC / Isilon Storage Division Modified: head/sys/vm/vm_radix.c Modified: head/sys/vm/vm_radix.c == --- head/sys/vm/vm_radix.c Tue Mar 26 16:38:03 2013(r248727) +++ head/sys/vm/vm_radix.c Tue Mar 26 17:30:40 2013(r248728) @@ -189,6 +189,16 @@ vm_radix_setroot(struct vm_radix *rtree, } /* + * Returns TRUE if the specified radix node is a leaf and FALSE otherwise. + */ +static __inline boolean_t +vm_radix_isleaf(struct vm_radix_node *rnode) +{ + + return (((uintptr_t)rnode & VM_RADIX_ISLEAF) != 0); +} + +/* * Returns the associated page extracted from rnode if available, * and NULL otherwise. */ @@ -315,7 +325,7 @@ vm_radix_reclaim_allnodes_int(struct vm_ for (slot = 0; rnode->rn_count != 0; slot++) { if (rnode->rn_child[slot] == NULL) continue; - if (vm_radix_node_page(rnode->rn_child[slot]) == NULL) + if (!vm_radix_isleaf(rnode->rn_child[slot])) vm_radix_reclaim_allnodes_int(rnode->rn_child[slot]); rnode->rn_child[slot] = NULL; rnode->rn_count--; @@ -454,7 +464,7 @@ vm_radix_insert(struct vm_radix *rtree, __func__, clev, rnode->rn_clev)); slot = vm_radix_slot(index, rnode->rn_clev); tmp = rnode->rn_child[slot]; - KASSERT(tmp != NULL && vm_radix_node_page(tmp) == NULL, + KASSERT(tmp != NULL && !vm_radix_isleaf(tmp), ("%s: unexpected lookup interruption", __func__)); if (tmp->rn_clev > clev) break; ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248729 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:01:24 2013 New Revision: 248729 URL: http://svnweb.freebsd.org/changeset/base/248729 Log: Do not look at the namespace's thin provisioning field to determine if DSM command is supported. The two are not related. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme_ns.c Modified: head/sys/dev/nvme/nvme_ns.c == --- head/sys/dev/nvme/nvme_ns.c Tue Mar 26 17:30:40 2013(r248728) +++ head/sys/dev/nvme/nvme_ns.c Tue Mar 26 18:01:24 2013(r248729) @@ -339,7 +339,7 @@ nvme_ns_construct(struct nvme_namespace } #endif - if (ctrlr->cdata.oncs.dsm && ns->data.nsfeat.thin_prov) + if (ctrlr->cdata.oncs.dsm) ns->flags |= NVME_NS_DEALLOCATE_SUPPORTED; if (ctrlr->cdata.vwc.present) ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248730 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:16:30 2013 New Revision: 248730 URL: http://svnweb.freebsd.org/changeset/base/248730 Log: Make the DSM range count 0-based. Previously we were deallocating one more LBA than we should have been. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme_ns_cmd.c Modified: head/sys/dev/nvme/nvme_ns_cmd.c == --- head/sys/dev/nvme/nvme_ns_cmd.c Tue Mar 26 18:01:24 2013 (r248729) +++ head/sys/dev/nvme/nvme_ns_cmd.c Tue Mar 26 18:16:30 2013 (r248730) @@ -96,7 +96,7 @@ nvme_ns_cmd_deallocate(struct nvme_names cmd->nsid = ns->id; /* TODO: create a delete command data structure */ - cmd->cdw10 = num_ranges; + cmd->cdw10 = num_ranges - 1; cmd->cdw11 = NVME_DSM_ATTR_DEALLOCATE; nvme_ctrlr_submit_io_request(ns->ctrlr, req); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248731 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:20:11 2013 New Revision: 248731 URL: http://svnweb.freebsd.org/changeset/base/248731 Log: Add an internal _nvme_qpair_submit_request function, which performs the submit action assuming the qpair lock has already been acquired. Also change nvme_qpair_submit_request to just lock/unlock the mutex around a call to this new function. This fixes a recursive mutex acquisition in the retry path. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:16:30 2013 (r248730) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:20:11 2013 (r248731) @@ -34,6 +34,9 @@ __FBSDID("$FreeBSD$"); #include "nvme_private.h" +static void_nvme_qpair_submit_request(struct nvme_qpair *qpair, + struct nvme_request *req); + static boolean_t nvme_completion_check_retry(const struct nvme_completion *cpl) { @@ -149,7 +152,7 @@ nvme_qpair_process_completions(struct nv if (!STAILQ_EMPTY(&qpair->queued_req)) { req = STAILQ_FIRST(&qpair->queued_req); STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq); - nvme_qpair_submit_request(qpair, req); + _nvme_qpair_submit_request(qpair, req); } } @@ -410,13 +413,13 @@ nvme_qpair_submit_cmd(struct nvme_qpair qpair->num_cmds++; } -void -nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req) +static void +_nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req) { struct nvme_tracker *tr; int err; - mtx_lock(&qpair->lock); + mtx_assert(&qpair->lock, MA_OWNED); tr = SLIST_FIRST(&qpair->free_tr); @@ -427,7 +430,7 @@ nvme_qpair_submit_request(struct nvme_qp * via a command completion. */ STAILQ_INSERT_TAIL(&qpair->queued_req, req, stailq); - goto ret; + return; } SLIST_REMOVE_HEAD(&qpair->free_tr, slist); @@ -450,7 +453,13 @@ nvme_qpair_submit_request(struct nvme_qp if (err != 0) panic("bus_dmamap_load returned non-zero!\n"); } +} -ret: +void +nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req) +{ + + mtx_lock(&qpair->lock); + _nvme_qpair_submit_request(qpair, req); mtx_unlock(&qpair->lock); } ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248732 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:23:35 2013 New Revision: 248732 URL: http://svnweb.freebsd.org/changeset/base/248732 Log: Add support for ABORT commands, including issuing these commands when an I/O times out. Also ensure that we retry commands that are aborted due to a timeout. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme_ctrlr_cmd.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_ctrlr_cmd.c == --- head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 18:20:11 2013 (r248731) +++ head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 18:23:35 2013 (r248732) @@ -281,3 +281,19 @@ nvme_ctrlr_cmd_get_health_information_pa nvme_ctrlr_submit_admin_request(ctrlr, req); } + +void +nvme_ctrlr_cmd_abort(struct nvme_controller *ctrlr, uint16_t cid, +uint16_t sqid, nvme_cb_fn_t cb_fn, void *cb_arg) +{ + struct nvme_request *req; + struct nvme_command *cmd; + + req = nvme_allocate_request(NULL, 0, cb_fn, cb_arg); + + cmd = &req->cmd; + cmd->opc = NVME_OPC_ABORT; + cmd->cdw10 = (cid << 16) | sqid; + + nvme_ctrlr_submit_admin_request(ctrlr, req); +} Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 18:20:11 2013 (r248731) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 18:23:35 2013 (r248732) @@ -348,6 +348,8 @@ voidnvme_ctrlr_cmd_set_asynchronous_eve void nvme_ctrlr_cmd_asynchronous_event_request(struct nvme_controller *ctrlr, nvme_cb_fn_t cb_fn, void *cb_arg); +void nvme_ctrlr_cmd_abort(struct nvme_controller *ctrlr, uint16_t cid, +uint16_t sqid, nvme_cb_fn_t cb_fn, void *cb_arg); void nvme_payload_map(void *arg, bus_dma_segment_t *seg, int nseg, int error); Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:20:11 2013 (r248731) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:23:35 2013 (r248732) @@ -49,6 +49,8 @@ nvme_completion_check_retry(const struct switch (cpl->sf_sct) { case NVME_SCT_GENERIC: switch (cpl->sf_sc) { + case NVME_SC_ABORTED_BY_REQUEST: + return (1); case NVME_SC_NAMESPACE_NOT_READY: if (cpl->sf_dnr) return (0); @@ -60,7 +62,6 @@ nvme_completion_check_retry(const struct case NVME_SC_DATA_TRANSFER_ERROR: case NVME_SC_ABORTED_POWER_LOSS: case NVME_SC_INTERNAL_DEVICE_ERROR: - case NVME_SC_ABORTED_BY_REQUEST: case NVME_SC_ABORTED_SQ_DELETION: case NVME_SC_ABORTED_FAILED_FUSED: case NVME_SC_ABORTED_MISSING_FUSED: @@ -378,10 +379,10 @@ nvme_io_qpair_destroy(struct nvme_qpair static void nvme_timeout(void *arg) { - /* -* TODO: Add explicit abort operation here, once nvme(4) supports -* abort commands. -*/ + struct nvme_tracker *tr = arg; + + nvme_ctrlr_cmd_abort(tr->qpair->ctrlr, tr->cid, tr->qpair->id, + NULL, NULL); } void ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248733 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:27:22 2013 New Revision: 248733 URL: http://svnweb.freebsd.org/changeset/base/248733 Log: Break out the code for completing an nvme_tracker object into a separate function. This allows for completions outside the normal completion path, for example when an ABORT command fails due to the controller reporting the targeted command does not exist. This is mainly for protection against a faulty controller, but we need to clean up our internal request nonetheless. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:23:35 2013 (r248732) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:27:22 2013 (r248733) @@ -38,7 +38,14 @@ static void _nvme_qpair_submit_request(s struct nvme_request *req); static boolean_t -nvme_completion_check_retry(const struct nvme_completion *cpl) +nvme_completion_is_error(struct nvme_completion *cpl) +{ + + return (cpl->sf_sc != 0 || cpl->sf_sct != 0); +} + +static boolean_t +nvme_completion_is_retry(const struct nvme_completion *cpl) { /* * TODO: spec is not clear how commands that are aborted due @@ -96,69 +103,78 @@ nvme_qpair_construct_tracker(struct nvme tr->qpair = qpair; } -void -nvme_qpair_process_completions(struct nvme_qpair *qpair) +static void +nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr, +struct nvme_completion *cpl, boolean_t print_on_error) { - struct nvme_tracker *tr; struct nvme_request *req; - struct nvme_completion *cpl; boolean_t retry, error; - qpair->num_intr_handler_calls++; + req = tr->req; + error = nvme_completion_is_error(cpl); + retry = error && nvme_completion_is_retry(cpl); - while (1) { - cpl = &qpair->cpl[qpair->cq_head]; + if (error && print_on_error) { + nvme_dump_completion(cpl); + nvme_dump_command(&req->cmd); + } - if (cpl->p != qpair->phase) - break; + qpair->act_tr[cpl->cid] = NULL; - tr = qpair->act_tr[cpl->cid]; - req = tr->req; + KASSERT(cpl->cid == req->cmd.cid, ("cpl cid does not match cmd cid\n")); - KASSERT(tr, - ("completion queue has entries but no active trackers\n")); + if (req->cb_fn && !retry) + req->cb_fn(req->cb_arg, cpl); - error = cpl->sf_sc || cpl->sf_sct; - retry = error && nvme_completion_check_retry(cpl); + mtx_lock(&qpair->lock); + callout_stop(&tr->timer); - if (error) { - nvme_dump_completion(cpl); - nvme_dump_command(&tr->req->cmd); - } + if (retry) + nvme_qpair_submit_cmd(qpair, tr); + else { + if (req->payload_size > 0 || req->uio != NULL) + bus_dmamap_unload(qpair->dma_tag, + tr->payload_dma_map); + + nvme_free_request(req); - qpair->act_tr[cpl->cid] = NULL; + SLIST_INSERT_HEAD(&qpair->free_tr, tr, slist); - KASSERT(cpl->cid == req->cmd.cid, - ("cpl cid does not match cmd cid\n")); + if (!STAILQ_EMPTY(&qpair->queued_req)) { + req = STAILQ_FIRST(&qpair->queued_req); + STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq); + _nvme_qpair_submit_request(qpair, req); + } + } - if (req->cb_fn && !retry) - req->cb_fn(req->cb_arg, cpl); + mtx_unlock(&qpair->lock); +} - qpair->sq_head = cpl->sqhd; +void +nvme_qpair_process_completions(struct nvme_qpair *qpair) +{ + struct nvme_tracker *tr; + struct nvme_completion *cpl; - mtx_lock(&qpair->lock); - callout_stop(&tr->timer); + qpair->num_intr_handler_calls++; - if (retry) - nvme_qpair_submit_cmd(qpair, tr); - else { - if (req->payload_size > 0 || req->uio != NULL) - bus_dmamap_unload(qpair->dma_tag, - tr->payload_dma_map); + while (1) { + cpl = &qpair->cpl[qpair->cq_head]; - nvme_free_request(req); + if (cpl->p != qpair->phase) + break; - SLIST_INSERT_HEAD(&qpair->free_tr, tr, slist); + tr = qpair->act_tr[cpl->cid]; - if (!STAILQ_EMPTY(&qpair->queued_req)) { -
svn commit: r248734 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:29:04 2013 New Revision: 248734 URL: http://svnweb.freebsd.org/changeset/base/248734 Log: Explicitly abort a timed out command, if the ABORT command sent to the controller indicates the command was not found. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:27:22 2013 (r248733) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:29:04 2013 (r248734) @@ -393,12 +393,40 @@ nvme_io_qpair_destroy(struct nvme_qpair } static void +nvme_abort_complete(void *arg, const struct nvme_completion *status) +{ + struct nvme_completion cpl; + struct nvme_tracker *tr = arg; + + /* +* If cdw0 == 1, the controller was not able to abort the command +* we requested. We still need to check the active tracker array, +* to cover race where I/O timed out at same time controller was +* completing the I/O. +*/ + if (status->cdw0 == 1 && tr->qpair->act_tr[tr->cid] != NULL) { + /* +* An I/O has timed out, and the controller was unable to +* abort it for some reason. Construct a fake completion +* status, and then complete the I/O's tracker manually. +*/ + printf("abort command failed, aborting command manually\n"); + memset(&cpl, 0, sizeof(cpl)); + cpl.sqid = tr->qpair->id; + cpl.cid = tr->cid; + cpl.sf_sct = NVME_SCT_GENERIC; + cpl.sf_sc = NVME_SC_ABORTED_BY_REQUEST; + nvme_qpair_complete_tracker(tr->qpair, tr, &cpl, TRUE); + } +} + +static void nvme_timeout(void *arg) { struct nvme_tracker *tr = arg; nvme_ctrlr_cmd_abort(tr->qpair->ctrlr, tr->cid, tr->qpair->id, - NULL, NULL); + nvme_abort_complete, tr); } void ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248735 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:31:46 2013 New Revision: 248735 URL: http://svnweb.freebsd.org/changeset/base/248735 Log: Specify command timeout interval on a per-command type basis. This is primarily driven by the need to disable timeouts for asynchronous event requests, which by nature should not be timed out. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme_ctrlr_cmd.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_ctrlr_cmd.c == --- head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 18:29:04 2013 (r248734) +++ head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 18:31:46 2013 (r248735) @@ -257,6 +257,12 @@ nvme_ctrlr_cmd_asynchronous_event_reques req = nvme_allocate_request(NULL, 0, cb_fn, cb_arg); + /* +* Override default timeout value here, since asynchronous event +* requests should by nature never be timed out. +*/ + req->timeout = 0; + cmd = &req->cmd; cmd->opc = NVME_OPC_ASYNC_EVENT_REQUEST; Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 18:29:04 2013 (r248734) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 18:31:46 2013 (r248735) @@ -112,6 +112,7 @@ struct nvme_request { struct nvme_command cmd; void*payload; uint32_tpayload_size; + uint32_ttimeout; struct uio *uio; nvme_cb_fn_tcb_fn; void*cb_arg; @@ -411,6 +412,7 @@ nvme_allocate_request(void *payload, uin req->payload_size = payload_size; req->cb_fn = cb_fn; req->cb_arg = cb_arg; + req->timeout = NVME_TIMEOUT_IN_SEC; return (req); } @@ -427,6 +429,7 @@ nvme_allocate_request_uio(struct uio *ui req->uio = uio; req->cb_fn = cb_fn; req->cb_arg = cb_arg; + req->timeout = NVME_TIMEOUT_IN_SEC; return (req); } Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:29:04 2013 (r248734) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:31:46 2013 (r248735) @@ -438,11 +438,12 @@ nvme_qpair_submit_cmd(struct nvme_qpair req->cmd.cid = tr->cid; qpair->act_tr[tr->cid] = tr; + if (req->timeout > 0) #if __FreeBSD_version >= 800030 - callout_reset_curcpu(&tr->timer, NVME_TIMEOUT_IN_SEC * hz, - nvme_timeout, tr); + callout_reset_curcpu(&tr->timer, req->timeout * hz, + nvme_timeout, tr); #else - callout_reset(&tr->timer, NVME_TIMEOUT_IN_SEC * hz, nvme_timeout, tr); + callout_reset(&tr->timer, req->timeout * hz, nvme_timeout, tr); #endif /* Copy the command from the tracker to the submission queue. */ ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248736 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:34:19 2013 New Revision: 248736 URL: http://svnweb.freebsd.org/changeset/base/248736 Log: Move controller destruction code from nvme_detach() to new nvme_ctrlr_destruct() function. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 18:31:46 2013(r248735) +++ head/sys/dev/nvme/nvme.cTue Mar 26 18:34:19 2013(r248736) @@ -286,53 +286,8 @@ static int nvme_detach (device_t dev) { struct nvme_controller *ctrlr = DEVICE2SOFTC(dev); - struct nvme_namespace *ns; - int i; - - for (i = 0; i < NVME_MAX_NAMESPACES; i++) { - ns = &ctrlr->ns[i]; - if (ns->cdev) - destroy_dev(ns->cdev); - } - - if (ctrlr->cdev) - destroy_dev(ctrlr->cdev); - - for (i = 0; i < ctrlr->num_io_queues; i++) { - nvme_io_qpair_destroy(&ctrlr->ioq[i]); - } - - free(ctrlr->ioq, M_NVME); - - nvme_admin_qpair_destroy(&ctrlr->adminq); - - if (ctrlr->resource != NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, - ctrlr->resource_id, ctrlr->resource); - } - - if (ctrlr->bar4_resource != NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, - ctrlr->bar4_resource_id, ctrlr->bar4_resource); - } - -#ifdef CHATHAM2 - if (ctrlr->chatham_resource != NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, - ctrlr->chatham_resource_id, ctrlr->chatham_resource); - } -#endif - - if (ctrlr->tag) - bus_teardown_intr(ctrlr->dev, ctrlr->res, ctrlr->tag); - - if (ctrlr->res) - bus_release_resource(ctrlr->dev, SYS_RES_IRQ, - rman_get_rid(ctrlr->res), ctrlr->res); - - if (ctrlr->msix_enabled) - pci_release_msi(dev); + nvme_ctrlr_destruct(ctrlr, dev); return (0); } Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 18:31:46 2013 (r248735) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 18:34:19 2013 (r248736) @@ -808,6 +808,57 @@ intx: } void +nvme_ctrlr_destruct(struct nvme_controller *ctrlr, device_t dev) +{ + struct nvme_namespace *ns; + int i; + + for (i = 0; i < NVME_MAX_NAMESPACES; i++) { + ns = &ctrlr->ns[i]; + if (ns->cdev) + destroy_dev(ns->cdev); + } + + if (ctrlr->cdev) + destroy_dev(ctrlr->cdev); + + for (i = 0; i < ctrlr->num_io_queues; i++) { + nvme_io_qpair_destroy(&ctrlr->ioq[i]); + } + + free(ctrlr->ioq, M_NVME); + + nvme_admin_qpair_destroy(&ctrlr->adminq); + + if (ctrlr->resource != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, + ctrlr->resource_id, ctrlr->resource); + } + + if (ctrlr->bar4_resource != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, + ctrlr->bar4_resource_id, ctrlr->bar4_resource); + } + +#ifdef CHATHAM2 + if (ctrlr->chatham_resource != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, + ctrlr->chatham_resource_id, ctrlr->chatham_resource); + } +#endif + + if (ctrlr->tag) + bus_teardown_intr(ctrlr->dev, ctrlr->res, ctrlr->tag); + + if (ctrlr->res) + bus_release_resource(ctrlr->dev, SYS_RES_IRQ, + rman_get_rid(ctrlr->res), ctrlr->res); + + if (ctrlr->msix_enabled) + pci_release_msi(dev); +} + +void nvme_ctrlr_submit_admin_request(struct nvme_controller *ctrlr, struct nvme_request *req) { Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 18:31:46 2013 (r248735) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 18:34:19 2013 (r248736) @@ -358,6 +358,7 @@ voidnvme_payload_map_uio(void *arg, bus bus_size_t mapsize, int error); intnvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev); +void nvme_ctrlr_destruct(struct nvme_controller *ctrlr, device_t dev); intnvme_ctrlr_reset(struct nvme_controller *ctrlr); /* ctrlr defined as void * to allow use with config_intrhook. */ void nvme_ctrlr_start(void *ctrlr_arg); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-
svn commit: r248737 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:37:36 2013 New Revision: 248737 URL: http://svnweb.freebsd.org/changeset/base/248737 Log: Enable asynchronous event requests on non-Chatham devices. Also add logic to clean up all outstanding asynchronous event requests when resetting or shutting down the controller, since these requests will not be explicitly completed by the controller itself. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ctrlr_cmd.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 18:34:19 2013(r248736) +++ head/sys/dev/nvme/nvme.hTue Mar 26 18:37:36 2013(r248737) @@ -360,7 +360,7 @@ enum nvme_feature { NVME_FEAT_INTERRUPT_COALESCING = 0x08, NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09, NVME_FEAT_WRITE_ATOMICITY = 0x0A, - NVME_FEAT_ASYNCHRONOUS_EVENT_CONFIGURATION = 0x0B, + NVME_FEAT_ASYNC_EVENT_CONFIGURATION = 0x0B, /* 0x0C-0x7F - reserved */ NVME_FEAT_SOFTWARE_PROGRESS_MARKER = 0x80, /* 0x81-0xBF - command set specific (reserved) */ Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 18:34:19 2013 (r248736) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 18:37:36 2013 (r248737) @@ -38,6 +38,9 @@ __FBSDID("$FreeBSD$"); #include "nvme_private.h" +static void nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr, + struct nvme_async_event_request *aer); + static void nvme_ctrlr_cb(void *arg, const struct nvme_completion *status) { @@ -409,30 +412,6 @@ nvme_ctrlr_reset(struct nvme_controller return (nvme_ctrlr_enable(ctrlr)); } -/* - * Disable this code for now, since Chatham doesn't support - * AERs so I have no good way to test them. - */ -#if 0 -static void -nvme_async_event_cb(void *arg, const struct nvme_completion *status) -{ - struct nvme_controller *ctrlr = arg; - - printf("Asynchronous event occurred.\n"); - - /* TODO: decode async event type based on status */ - /* TODO: check status for any error bits */ - - /* -* Repost an asynchronous event request so that it can be -* used again by the controller. -*/ - nvme_ctrlr_cmd_asynchronous_event_request(ctrlr, nvme_async_event_cb, - ctrlr); -} -#endif - static int nvme_ctrlr_identify(struct nvme_controller *ctrlr) { @@ -558,27 +537,71 @@ nvme_ctrlr_construct_namespaces(struct n } static void +nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl) +{ + struct nvme_async_event_request *aer = arg; + + if (cpl->sf_sc == NVME_SC_ABORTED_SQ_DELETION) { + /* +* This is simulated when controller is being shut down, to +* effectively abort outstanding asynchronous event requests +* and make sure all memory is freed. Do not repost the +* request in this case. +*/ + return; + } + + /* TODO: decode async event type based on status */ + + /* +* Repost another asynchronous event request to replace the one that +* just completed. +*/ + printf("Asynchronous event occurred.\n"); + nvme_ctrlr_construct_and_submit_aer(aer->ctrlr, aer); +} + +static void +nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr, +struct nvme_async_event_request *aer) +{ + struct nvme_request *req; + + aer->ctrlr = ctrlr; + req = nvme_allocate_request(NULL, 0, nvme_ctrlr_async_event_cb, aer); + aer->req = req; + + /* +* Override default timeout value here, since asynchronous event +* requests should by nature never be timed out. +*/ + req->timeout = 0; + req->cmd.opc = NVME_OPC_ASYNC_EVENT_REQUEST; + nvme_ctrlr_submit_admin_request(ctrlr, req); +} + +static void nvme_ctrlr_configure_aer(struct nvme_controller *ctrlr) { union nvme_critical_warning_state state; - uint8_t num_async_events; + struct nvme_async_event_request *aer; + uint32_ti; state.raw = 0xFF; state.bits.reserved = 0; - nvme_ctrlr_cmd_set_asynchronous_event_config(ctrlr, state, NULL, NULL); + nvme_ctrlr_cmd_set_async_event_config(ctrlr, state, NULL, NULL); /* aerl is a zero-based value, so we need to add 1 here. */ - num_async_events = min(NVME_MAX_ASYNC_EVENTS, (ctrlr->cdata.aerl+1)); + ctrlr->num_aers = min(NVME_MAX_ASYNC_E
svn commit: r248738 - in head/sys/dev: nvd nvme
Author: jimharris Date: Tue Mar 26 18:39:54 2013 New Revision: 248738 URL: http://svnweb.freebsd.org/changeset/base/248738 Log: Add an interface for nvme shim drivers (i.e. nvd) to register for notifications when new nvme controllers are added to the system. Sponsored by: Intel Modified: head/sys/dev/nvd/nvd.c head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvd/nvd.c == --- head/sys/dev/nvd/nvd.c Tue Mar 26 18:37:36 2013(r248737) +++ head/sys/dev/nvd/nvd.c Tue Mar 26 18:39:54 2013(r248738) @@ -45,7 +45,7 @@ struct nvd_disk; static disk_ioctl_t nvd_ioctl; static disk_strategy_t nvd_strategy; -static void create_geom_disk(void *, struct nvme_namespace *ns); +static void *create_geom_disk(struct nvme_namespace *ns, void *ctrlr); static void destroy_geom_disk(struct nvd_disk *ndisk); static int nvd_load(void); @@ -105,7 +105,7 @@ nvd_load() { TAILQ_INIT(&nvd_head); - consumer_handle = nvme_register_consumer(create_geom_disk, NULL); + consumer_handle = nvme_register_consumer(create_geom_disk, NULL, NULL); return (consumer_handle != NULL ? 0 : -1); } @@ -233,8 +233,8 @@ nvd_bioq_process(void *arg, int pending) } } -static void -create_geom_disk(void *arg, struct nvme_namespace *ns) +static void * +create_geom_disk(struct nvme_namespace *ns, void *ctrlr) { struct nvd_disk *ndisk; struct disk *disk; @@ -287,6 +287,8 @@ create_geom_disk(void *arg, struct nvme_ taskqueue_start_threads(&ndisk->tq, 1, PI_DISK, "nvd taskq"); TAILQ_INSERT_HEAD(&nvd_head, ndisk, tailq); + + return (NULL); } static void Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 18:37:36 2013(r248737) +++ head/sys/dev/nvme/nvme.cTue Mar 26 18:39:54 2013(r248738) @@ -40,11 +40,14 @@ __FBSDID("$FreeBSD$"); #include "nvme_private.h" struct nvme_consumer { - nvme_consumer_cb_fn_t cb_fn; - void*cb_arg; + uint32_tid; + nvme_cons_ns_fn_t ns_fn; + nvme_cons_ctrlr_fn_tctrlr_fn; + nvme_cons_async_fn_tasync_fn; }; struct nvme_consumer nvme_consumer[NVME_MAX_CONSUMERS]; +#defineINVALID_CONSUMER_ID 0x uma_zone_t nvme_request_zone; @@ -118,8 +121,13 @@ nvme_probe (device_t device) static void nvme_init(void) { + uint32_ti; + nvme_request_zone = uma_zcreate("nvme_request", sizeof(struct nvme_request), NULL, NULL, NULL, NULL, 0, 0); + + for (i = 0; i < NVME_MAX_CONSUMERS; i++) + nvme_consumer[i].id = INVALID_CONSUMER_ID; } SYSINIT(nvme_register, SI_SUB_DRIVERS, SI_ORDER_SECOND, nvme_init, NULL); @@ -292,26 +300,52 @@ nvme_detach (device_t dev) } static void -nvme_notify_consumer(struct nvme_consumer *consumer) +nvme_notify_consumer(struct nvme_consumer *cons) { device_t*devlist; struct nvme_controller *ctrlr; - int dev, ns, devcount; + struct nvme_namespace *ns; + void*ctrlr_cookie; + int dev_idx, ns_idx, devcount; if (devclass_get_devices(nvme_devclass, &devlist, &devcount)) return; - for (dev = 0; dev < devcount; dev++) { - ctrlr = DEVICE2SOFTC(devlist[dev]); - for (ns = 0; ns < ctrlr->cdata.nn; ns++) - (*consumer->cb_fn)(consumer->cb_arg, &ctrlr->ns[ns]); + for (dev_idx = 0; dev_idx < devcount; dev_idx++) { + ctrlr = DEVICE2SOFTC(devlist[dev_idx]); + if (cons->ctrlr_fn != NULL) + ctrlr_cookie = (*cons->ctrlr_fn)(ctrlr); + else + ctrlr_cookie = NULL; + ctrlr->cons_cookie[cons->id] = ctrlr_cookie; + for (ns_idx = 0; ns_idx < ctrlr->cdata.nn; ns_idx++) { + ns = &ctrlr->ns[ns_idx]; + if (cons->ns_fn != NULL) + ns->cons_cookie[cons->id] = + (*cons->ns_fn)(ns, ctrlr_cookie); + } } free(devlist, M_TEMP); } +void +nvme_notify_async_consumers(struct nvme_controller *ctrlr, + const struct nvme_completion *async_cpl) +{ + struct nvme_consumer*cons; + uint32_ti; + + for (i = 0; i < NVME_MAX_CONSUMERS; i++) { + cons = &nvme_consumer[i]; + if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL) + (*cons->async_fn)(ctrlr->cons_cookie[i], async_cpl); + } +} + struct nv
svn commit: r248739 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:42:05 2013 New Revision: 248739 URL: http://svnweb.freebsd.org/changeset/base/248739 Log: Expose the get/set features API to nvme consumers. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 18:39:54 2013(r248738) +++ head/sys/dev/nvme/nvme.hTue Mar 26 18:42:05 2013(r248739) @@ -704,6 +704,16 @@ enum nvme_namespace_flags { NVME_NS_FLUSH_SUPPORTED = 0x2, }; +/* Admin functions */ +void nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, + uint8_t feature, uint32_t cdw11, + void *payload, uint32_t payload_size, + nvme_cb_fn_t cb_fn, void *cb_arg); +void nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr, + uint8_t feature, uint32_t cdw11, + void *payload, uint32_t payload_size, + nvme_cb_fn_t cb_fn, void *cb_arg); + /* NVM I/O functions */ intnvme_ns_cmd_write(struct nvme_namespace *ns, void *payload, uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn, Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 18:39:54 2013 (r248738) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 18:42:05 2013 (r248739) @@ -316,14 +316,6 @@ struct nvme_controller { void nvme_ns_test(struct nvme_namespace *ns, u_long cmd, caddr_t arg); -void nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, - uint8_t feature, uint32_t cdw11, - void *payload, uint32_t payload_size, - nvme_cb_fn_t cb_fn, void *cb_arg); -void nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr, - uint8_t feature, uint32_t cdw11, - void *payload, uint32_t payload_size, - nvme_cb_fn_t cb_fn, void *cb_arg); void nvme_ctrlr_cmd_identify_controller(struct nvme_controller *ctrlr, void *payload, nvme_cb_fn_t cb_fn, void *cb_arg); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248740 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:43:53 2013 New Revision: 248740 URL: http://svnweb.freebsd.org/changeset/base/248740 Log: Create a generic nvme_ctrlr_cmd_get_log_page function, and change the health information log page function to use it. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr_cmd.c Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 18:42:05 2013(r248739) +++ head/sys/dev/nvme/nvme.hTue Mar 26 18:43:53 2013(r248740) @@ -713,6 +713,10 @@ void nvme_ctrlr_cmd_get_feature(struct n uint8_t feature, uint32_t cdw11, void *payload, uint32_t payload_size, nvme_cb_fn_t cb_fn, void *cb_arg); +void nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, + uint8_t log_page, uint32_t nsid, + void *payload, uint32_t payload_size, + nvme_cb_fn_t cb_fn, void *cb_arg); /* NVM I/O functions */ intnvme_ns_cmd_write(struct nvme_namespace *ns, void *payload, Modified: head/sys/dev/nvme/nvme_ctrlr_cmd.c == --- head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 18:42:05 2013 (r248739) +++ head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 18:43:53 2013 (r248740) @@ -249,24 +249,35 @@ nvme_ctrlr_cmd_set_interrupt_coalescing( } void -nvme_ctrlr_cmd_get_health_information_page(struct nvme_controller *ctrlr, -uint32_t nsid, struct nvme_health_information_page *payload, -nvme_cb_fn_t cb_fn, void *cb_arg) +nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, uint8_t log_page, +uint32_t nsid, void *payload, uint32_t payload_size, nvme_cb_fn_t cb_fn, +void *cb_arg) { struct nvme_request *req; struct nvme_command *cmd; - req = nvme_allocate_request(payload, sizeof(*payload), cb_fn, cb_arg); + req = nvme_allocate_request(payload, payload_size, cb_fn, cb_arg); cmd = &req->cmd; cmd->opc = NVME_OPC_GET_LOG_PAGE; cmd->nsid = nsid; - cmd->cdw10 = ((sizeof(*payload)/sizeof(uint32_t)) - 1) << 16; - cmd->cdw10 |= NVME_LOG_HEALTH_INFORMATION; + cmd->cdw10 = ((payload_size/sizeof(uint32_t)) - 1) << 16; + cmd->cdw10 |= log_page; nvme_ctrlr_submit_admin_request(ctrlr, req); } + +void +nvme_ctrlr_cmd_get_health_information_page(struct nvme_controller *ctrlr, +uint32_t nsid, struct nvme_health_information_page *payload, +nvme_cb_fn_t cb_fn, void *cb_arg) +{ + + nvme_ctrlr_cmd_get_log_page(ctrlr, NVME_LOG_HEALTH_INFORMATION, + nsid, payload, sizeof(*payload), cb_fn, cb_arg); +} + void nvme_ctrlr_cmd_abort(struct nvme_controller *ctrlr, uint16_t cid, uint16_t sqid, nvme_cb_fn_t cb_fn, void *cb_arg) ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248741 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 18:45:16 2013 New Revision: 248741 URL: http://svnweb.freebsd.org/changeset/base/248741 Log: Keep a doubly-linked list of outstanding trackers. This enables in-order re-submission of I/O after a controller reset. Sponsored by: Intel Modified: head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 18:43:53 2013 (r248740) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 18:45:16 2013 (r248741) @@ -127,7 +127,7 @@ struct nvme_async_event_request { struct nvme_tracker { - SLIST_ENTRY(nvme_tracker) slist; + TAILQ_ENTRY(nvme_tracker) tailq; struct nvme_request *req; struct nvme_qpair *qpair; struct callout timer; @@ -174,7 +174,8 @@ struct nvme_qpair { bus_dmamap_tcpl_dma_map; uint64_tcpl_bus_addr; - SLIST_HEAD(, nvme_tracker) free_tr; + TAILQ_HEAD(, nvme_tracker) free_tr; + TAILQ_HEAD(, nvme_tracker) outstanding_tr; STAILQ_HEAD(, nvme_request) queued_req; struct nvme_tracker **act_tr; Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:43:53 2013 (r248740) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 18:45:16 2013 (r248741) @@ -156,7 +156,8 @@ nvme_qpair_complete_tracker(struct nvme_ nvme_free_request(req); tr->req = NULL; - SLIST_INSERT_HEAD(&qpair->free_tr, tr, slist); + TAILQ_REMOVE(&qpair->outstanding_tr, tr, tailq); + TAILQ_INSERT_HEAD(&qpair->free_tr, tr, tailq); if (!STAILQ_EMPTY(&qpair->queued_req)) { req = STAILQ_FIRST(&qpair->queued_req); @@ -293,7 +294,8 @@ nvme_qpair_construct(struct nvme_qpair * qpair->sq_tdbl_off = nvme_mmio_offsetof(doorbell[id].sq_tdbl); qpair->cq_hdbl_off = nvme_mmio_offsetof(doorbell[id].cq_hdbl); - SLIST_INIT(&qpair->free_tr); + TAILQ_INIT(&qpair->free_tr); + TAILQ_INIT(&qpair->outstanding_tr); STAILQ_INIT(&qpair->queued_req); for (i = 0; i < qpair->num_trackers; i++) { @@ -305,7 +307,7 @@ nvme_qpair_construct(struct nvme_qpair * } nvme_qpair_construct_tracker(qpair, tr, i); - SLIST_INSERT_HEAD(&qpair->free_tr, tr, slist); + TAILQ_INSERT_HEAD(&qpair->free_tr, tr, tailq); } qpair->act_tr = malloc(sizeof(struct nvme_tracker *) * qpair->num_entries, @@ -330,9 +332,9 @@ nvme_qpair_destroy(struct nvme_qpair *qp if (qpair->act_tr) free(qpair->act_tr, M_NVME); - while (!SLIST_EMPTY(&qpair->free_tr)) { - tr = SLIST_FIRST(&qpair->free_tr); - SLIST_REMOVE_HEAD(&qpair->free_tr, slist); + while (!TAILQ_EMPTY(&qpair->free_tr)) { + tr = TAILQ_FIRST(&qpair->free_tr); + TAILQ_REMOVE(&qpair->free_tr, tr, tailq); bus_dmamap_destroy(qpair->dma_tag, tr->payload_dma_map); bus_dmamap_destroy(qpair->dma_tag, tr->prp_dma_map); free(tr, M_NVME); @@ -513,7 +515,7 @@ _nvme_qpair_submit_request(struct nvme_q mtx_assert(&qpair->lock, MA_OWNED); - tr = SLIST_FIRST(&qpair->free_tr); + tr = TAILQ_FIRST(&qpair->free_tr); if (tr == NULL) { /* @@ -525,7 +527,8 @@ _nvme_qpair_submit_request(struct nvme_q return; } - SLIST_REMOVE_HEAD(&qpair->free_tr, slist); + TAILQ_REMOVE(&qpair->free_tr, tr, tailq); + TAILQ_INSERT_TAIL(&qpair->outstanding_tr, tr, tailq); tr->req = req; if (req->uio == NULL) { ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248742 - head/share/mk
Author: markj Date: Tue Mar 26 18:46:40 2013 New Revision: 248742 URL: http://svnweb.freebsd.org/changeset/base/248742 Log: Make sure to set OBJS consistently in the cases where SRCS is and isn't already defined. Setting it with "+=" makes it possible for other make scripts (e.g. bsd.dtrace.mk) to include additional object files in the linker arguments. Approved by: emaste (co-mentor) Modified: head/share/mk/bsd.prog.mk Modified: head/share/mk/bsd.prog.mk == --- head/share/mk/bsd.prog.mk Tue Mar 26 18:45:16 2013(r248741) +++ head/share/mk/bsd.prog.mk Tue Mar 26 18:46:40 2013(r248742) @@ -73,7 +73,7 @@ SRCS= ${PROG}.c # - the name of the object gets put into the executable symbol table instead of # the name of a variable temporary object. # - it's useful to keep objects around for crunching. -OBJS= ${PROG}.o +OBJS+= ${PROG}.o .if target(beforelinking) beforelinking: ${OBJS} ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248743 - stable/9/sys/net
Author: melifaro Date: Tue Mar 26 18:57:25 2013 New Revision: 248743 URL: http://svnweb.freebsd.org/changeset/base/248743 Log: Permit changing MTU in 6to4 relay. This behavior is recommended by RFC 4213 clause 3.2. Sometimes fragmentation is the least evil. For example, some Linux IPVS kernels forwards ICMPv6 checksums to real servers incorrectly. Modified: stable/9/sys/net/if_stf.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/net/ (props changed) Modified: stable/9/sys/net/if_stf.c == --- stable/9/sys/net/if_stf.c Tue Mar 26 18:46:40 2013(r248742) +++ stable/9/sys/net/if_stf.c Tue Mar 26 18:57:25 2013(r248743) @@ -799,7 +799,7 @@ stf_rtrequest(cmd, rt, info) struct rt_addrinfo *info; { RT_LOCK_ASSERT(rt); - rt->rt_rmx.rmx_mtu = IPV6_MMTU; + rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; } static int @@ -812,7 +812,7 @@ stf_ioctl(ifp, cmd, data) struct ifreq *ifr; struct sockaddr_in6 *sin6; struct in_addr addr; - int error; + int error, mtu; error = 0; switch (cmd) { @@ -846,6 +846,18 @@ stf_ioctl(ifp, cmd, data) error = EAFNOSUPPORT; break; + case SIOCGIFMTU: + break; + + case SIOCSIFMTU: + ifr = (struct ifreq *)data; + mtu = ifr->ifr_mtu; + /* RFC 4213 3.2 ideal world MTU */ + if (mtu < IPV6_MINMTU || mtu > IF_MAXMTU - 20) + return (EINVAL); + ifp->if_mtu = mtu; + break; + default: error = EINVAL; break; ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
Re: svn commit: r248743 - stable/9/sys/net
On 26.03.2013 22:57, Alexander V. Chernikov wrote: > Author: melifaro > Date: Tue Mar 26 18:57:25 2013 > New Revision: 248743 > URL: http://svnweb.freebsd.org/changeset/base/248743 > > Log: Merge r238492. > Permit changing MTU in 6to4 relay. > > This behavior is recommended by RFC 4213 clause 3.2. > > Sometimes fragmentation is the least evil. > For example, some Linux IPVS kernels forwards > ICMPv6 checksums to real servers incorrectly. > > Modified: > stable/9/sys/net/if_stf.c > Directory Properties: > stable/9/sys/ (props changed) > stable/9/sys/net/ (props changed) > > Modified: stable/9/sys/net/if_stf.c > == > --- stable/9/sys/net/if_stf.c Tue Mar 26 18:46:40 2013(r248742) > +++ stable/9/sys/net/if_stf.c Tue Mar 26 18:57:25 2013(r248743) > @@ -799,7 +799,7 @@ stf_rtrequest(cmd, rt, info) > struct rt_addrinfo *info; > { > RT_LOCK_ASSERT(rt); > - rt->rt_rmx.rmx_mtu = IPV6_MMTU; > + rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; > } > > static int > @@ -812,7 +812,7 @@ stf_ioctl(ifp, cmd, data) > struct ifreq *ifr; > struct sockaddr_in6 *sin6; > struct in_addr addr; > - int error; > + int error, mtu; > > error = 0; > switch (cmd) { > @@ -846,6 +846,18 @@ stf_ioctl(ifp, cmd, data) > error = EAFNOSUPPORT; > break; > > + case SIOCGIFMTU: > + break; > + > + case SIOCSIFMTU: > + ifr = (struct ifreq *)data; > + mtu = ifr->ifr_mtu; > + /* RFC 4213 3.2 ideal world MTU */ > + if (mtu < IPV6_MINMTU || mtu > IF_MAXMTU - 20) > + return (EINVAL); > + ifp->if_mtu = mtu; > + break; > + > default: > error = EINVAL; > break; > -- WBR, Alexander ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248744 - head/usr.sbin/watchdogd
Author: markj Date: Tue Mar 26 19:43:18 2013 New Revision: 248744 URL: http://svnweb.freebsd.org/changeset/base/248744 Log: Invert the meaning of -S (added in r247405) and document its meaning. Also, don't carp about the watchdog command taking too long until after the watchdog has been patted, and don't carp via warnx(3) unless -S is set since syslog(3) already logs to standard error otherwise. Discussed with: alfred Reviewed by: alfred Approved by: emaste (co-mentor) Modified: head/usr.sbin/watchdogd/watchdogd.8 head/usr.sbin/watchdogd/watchdogd.c Modified: head/usr.sbin/watchdogd/watchdogd.8 == --- head/usr.sbin/watchdogd/watchdogd.8 Tue Mar 26 18:57:25 2013 (r248743) +++ head/usr.sbin/watchdogd/watchdogd.8 Tue Mar 26 19:43:18 2013 (r248744) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 2, 2013 +.Dd March 5, 2013 .Dt WATCHDOGD 8 .Os .Sh NAME @@ -35,7 +35,7 @@ .Nd watchdog daemon .Sh SYNOPSIS .Nm -.Op Fl dnw +.Op Fl dnSw .Op Fl -debug .Op Fl -softtimeout .Op Fl -softtimeout-action Ar action @@ -126,6 +126,12 @@ When this option is specified, .Nm will not fork into the background at startup. .Pp +.It Fl S +Do not send a message to the system logger when the watchdog command takes +longer than expected to execute. +The default behaviour is to log a warning via the system logger with the +LOG_DAEMON facility, and to output a warning to standard error. +.Pp .It Fl w Complain when the watchdog script takes too long. This flag will cause watchdogd to complain when the amount of time to Modified: head/usr.sbin/watchdogd/watchdogd.c == --- head/usr.sbin/watchdogd/watchdogd.c Tue Mar 26 18:57:25 2013 (r248743) +++ head/usr.sbin/watchdogd/watchdogd.c Tue Mar 26 19:43:18 2013 (r248744) @@ -77,7 +77,7 @@ static int is_dry_run = 0; /* do not ar report on timing of the watch program */ static int do_timedog = 0; -static int do_syslog = 0; +static int do_syslog = 1; static int fd = -1; static int nap = 1; static int carp_thresh_seconds = -1; @@ -125,12 +125,10 @@ main(int argc, char *argv[]) parseargs(argc, argv); - if (do_syslog) { + if (do_syslog) openlog("watchdogd", LOG_CONS|LOG_NDELAY|LOG_PERROR, LOG_DAEMON); - } - rtp.type = RTP_PRIO_REALTIME; rtp.prio = 0; if (rtprio(RTP_SET, 0, &rtp) == -1) @@ -234,8 +232,9 @@ static long watchdog_check_dogfunction_time(struct timespec *tp_start, struct timespec *tp_end) { - struct timeval tv_start, tv_end, tv; + struct timeval tv_start, tv_end, tv_now, tv; const char *cmd_prefix, *cmd; + struct timespec tp_now; int sec; if (!do_timedog) @@ -257,16 +256,28 @@ watchdog_check_dogfunction_time(struct t } if (do_syslog) syslog(LOG_CRIT, "%s: '%s' took too long: " - "%d.%06ld seconds >= %d seconds threshhold", + "%d.%06ld seconds >= %d seconds threshold", cmd_prefix, cmd, sec, (long)tv.tv_usec, carp_thresh_seconds); - warnx("%s: '%s' took too long: " - "%d.%06ld seconds >= %d seconds threshhold", - cmd_prefix, cmd, sec, (long)tv.tv_usec, carp_thresh_seconds); + else + warnx("%s: '%s' took too long: " + "%d.%06ld seconds >= %d seconds threshold", + cmd_prefix, cmd, sec, (long)tv.tv_usec, + carp_thresh_seconds); + + /* +* Adjust the sleep interval again in case syslog(3) took a non-trivial +* amount of time to run. +*/ + if (watchdog_getuptime(&tp_now)) + return (sec); + TIMESPEC_TO_TIMEVAL(&tv_now, &tp_now); + timersub(&tv_now, &tv_start, &tv); + sec = tv.tv_sec; + return (sec); } - /* * Main program loop which is iterated every second. */ @@ -298,10 +309,10 @@ watchdog_loop(void) goto try_end; } - waited = watchdog_check_dogfunction_time(&ts_start, &ts_end); - if (failed == 0) watchdog_patpat(timeout|WD_ACTIVE); + + waited = watchdog_check_dogfunction_time(&ts_start, &ts_end); if (nap - waited > 0) sleep(nap - waited); @@ -404,7 +415,7 @@ usage(void) { if (is_daemon) fprintf(stderr, "usage:\n" -" watchdogd [-dnw] [-e cmd] [-I file] [-s sleep] [-t timeout]\n" +" watchdogd [-dnSw] [-e cmd] [-I file] [-s sleep] [-t timeout]\n" "[-T script_timeout]\n" "[--debug]\n" "[--pretimeout seconds] [-pretimeout-action action]\n" @@ -551
svn commit: r248745 - head/sys/dev/ath
Author: adrian Date: Tue Mar 26 19:46:51 2013 New Revision: 248745 URL: http://svnweb.freebsd.org/changeset/base/248745 Log: Add per-TXQ EDMA FIFO staging queue support. Each set of frames pushed into a FIFO is represented by a list of ath_bufs - the first ath_buf in the FIFO list is marked with ATH_BUF_FIFOPTR; the last ath_buf in the FIFO list is marked with ATH_BUF_FIFOEND. Multiple lists of frames are just glued together in the TAILQ as per normal - except that at the end of a FIFO list, the descriptor link pointer will be NULL and it'll be tagged with ATH_BUF_FIFOEND. For non-EDMA chipsets this is a no-op - the ath_txq frame list (axq_q) stays the same and is treated the same. For EDMA chipsets the frames are pushed into axq_q and then when the FIFO is to be (re) filled, frames will be moved onto the FIFO queue and then pushed into the FIFO. So: * Add a new queue in each hardware TXQ (ath_txq) for staging FIFO frame lists. It's a TAILQ (like the normal hardware frame queue) rather than the ath9k list-of-lists to represent FIFO entries. * Add new ath_buf flags - ATH_TX_FIFOPTR and ATH_TX_FIFOEND. * When allocating ath_buf entries, clear out the flag value before returning it or it'll end up having stale flags. * When cloning ath_buf entries, only clone ATH_BUF_MGMT. Don't clone the FIFO related flags. * Extend ath_tx_draintxq() to first drain the FIFO staging queue, _then_ drain the normal hardware queue. Tested: * AR9280, hostap * AR9280, STA * AR9380/AR9580 - hostap TODO: * Test on other chipsets, just to be thorough. Modified: head/sys/dev/ath/if_ath.c head/sys/dev/ath/if_ath_misc.h head/sys/dev/ath/if_athvar.h Modified: head/sys/dev/ath/if_ath.c == --- head/sys/dev/ath/if_ath.c Tue Mar 26 19:43:18 2013(r248744) +++ head/sys/dev/ath/if_ath.c Tue Mar 26 19:46:51 2013(r248745) @@ -2474,6 +2474,7 @@ _ath_getbuf_locked(struct ath_softc *sc, /* XXX TODO: should do this at buffer list initialisation */ /* XXX (then, ensure the buffer has the right flag set) */ + bf->bf_flags = 0; if (btype == ATH_BUFTYPE_MGMT) bf->bf_flags |= ATH_BUF_MGMT; else @@ -2530,7 +2531,7 @@ ath_buf_clone(struct ath_softc *sc, cons /* Copy basics */ tbf->bf_next = NULL; tbf->bf_nseg = bf->bf_nseg; - tbf->bf_flags = bf->bf_flags & ~ATH_BUF_BUSY; + tbf->bf_flags = bf->bf_flags & ATH_BUF_FLAGS_CLONE; tbf->bf_status = bf->bf_status; tbf->bf_m = bf->bf_m; /* @@ -3410,6 +3411,7 @@ ath_txq_init(struct ath_softc *sc, struc txq->axq_softc = sc; TAILQ_INIT(&txq->axq_q); TAILQ_INIT(&txq->axq_tidq); + TAILQ_INIT(&txq->fifo.axq_q); ATH_TXQ_LOCK_INIT(sc, txq); } @@ -4169,7 +4171,7 @@ ath_returnbuf_head(struct ath_softc *sc, /* * Free the holding buffer if it exists */ -static void +void ath_txq_freeholdingbuf(struct ath_softc *sc, struct ath_txq *txq) { ATH_TXBUF_LOCK_ASSERT(sc); @@ -4283,6 +4285,61 @@ ath_tx_freebuf(struct ath_softc *sc, str */ } +static struct ath_buf * +ath_tx_draintxq_get_one(struct ath_softc *sc, struct ath_txq *txq) +{ + struct ath_buf *bf; + + ATH_TXQ_LOCK_ASSERT(txq); + + /* +* Drain the FIFO queue first, then if it's +* empty, move to the normal frame queue. +*/ + bf = TAILQ_FIRST(&txq->fifo.axq_q); + if (bf != NULL) { + /* +* Is it the last buffer in this set? +* Decrement the FIFO counter. +*/ + if (bf->bf_flags & ATH_BUF_FIFOEND) { + if (txq->axq_fifo_depth == 0) { + device_printf(sc->sc_dev, + "%s: Q%d: fifo_depth=0, fifo.axq_depth=%d?\n", + __func__, + txq->axq_qnum, + txq->fifo.axq_depth); + } else + txq->axq_fifo_depth--; + } + ATH_TXQ_REMOVE(&txq->fifo, bf, bf_list); + return (bf); + } + + /* +* Debugging! +*/ + if (txq->axq_fifo_depth != 0 || txq->fifo.axq_depth != 0) { + device_printf(sc->sc_dev, + "%s: Q%d: fifo_depth=%d, fifo.axq_depth=%d\n", + __func__, + txq->axq_qnum, + txq->axq_fifo_depth, + txq->fifo.axq_depth); + } + + /* +* Now drain the pending queue. +*/ + bf = TAILQ_FIRST(&txq->axq_q); + if (bf == NULL) { + txq->axq_link = NULL; + return (NULL); + } + ATH_TXQ_REMOVE(txq, bf, bf_list)
svn commit: r248746 - in head: sbin/nvmecontrol sys/dev/nvme
Author: jimharris Date: Tue Mar 26 19:50:46 2013 New Revision: 248746 URL: http://svnweb.freebsd.org/changeset/base/248746 Log: Add controller reset capability to nvme(4) and ability to explicitly invoke it from nvmecontrol(8). Controller reset will be performed in cases where I/O are repeatedly timing out, the controller reports an unrecoverable condition, or when explicitly requested via IOCTL or an nvme consumer. Since the controller may be in such a state where it cannot even process queue deletion requests, we will perform a controller reset without trying to clean up anything on the controller first. Sponsored by: Intel Reviewed by: carl Modified: head/sbin/nvmecontrol/nvmecontrol.8 head/sbin/nvmecontrol/nvmecontrol.c head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ns.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sbin/nvmecontrol/nvmecontrol.8 == --- head/sbin/nvmecontrol/nvmecontrol.8 Tue Mar 26 19:46:51 2013 (r248745) +++ head/sbin/nvmecontrol/nvmecontrol.8 Tue Mar 26 19:50:46 2013 (r248746) @@ -33,7 +33,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 17, 2012 +.Dd March 26, 2013 .Dt NVMECONTROL 8 .Os .Sh NAME @@ -54,7 +54,10 @@ .Op Fl p .Aq Fl s Ar size_in_bytes .Aq Fl t Ar time_in_sec -.Aq device id +.Aq namespace id +.Nm +.Ic reset +.Aq controller id .Sh DESCRIPTION NVM Express (NVMe) is a storage protocol standard, for SSDs and other high-speed storage devices over PCI Express. @@ -62,6 +65,7 @@ high-speed storage devices over PCI Expr .Dl nvmecontrol devlist .Pp Display a list of NVMe controllers and namespaces along with their device nodes. +.Pp .Dl nvmecontrol identify nvme0 .Pp Display a human-readable summary of the nvme0 IDENTIFY_CONTROLLER data. @@ -76,6 +80,10 @@ Display a hexadecimal dump of the nvme0 Run a performance test on nvme0ns1 using 32 kernel threads for 30 seconds. Each thread will issue a single 512 byte read command. Results are printed to stdout when 30 seconds expires. +.Pp +.Dl nvmecontrol reset nvme0 +.Pp +Perform a controller-level reset of the nvme0 controller. .Sh AUTHORS .An -nosplit .Nm Modified: head/sbin/nvmecontrol/nvmecontrol.c == --- head/sbin/nvmecontrol/nvmecontrol.c Tue Mar 26 19:46:51 2013 (r248745) +++ head/sbin/nvmecontrol/nvmecontrol.c Tue Mar 26 19:50:46 2013 (r248746) @@ -56,6 +56,9 @@ __FBSDID("$FreeBSD$"); "<-i intr|wait> [-f refthread] [-p]\n"\ "\n" +#define RESET_USAGE \ +" nvmecontrol reset \n" + static void perftest_usage(void); static void @@ -64,6 +67,7 @@ usage(void) fprintf(stderr, "usage:\n"); fprintf(stderr, DEVLIST_USAGE); fprintf(stderr, IDENTIFY_USAGE); + fprintf(stderr, RESET_USAGE); fprintf(stderr, PERFTEST_USAGE); exit(EX_USAGE); } @@ -580,6 +584,41 @@ perftest(int argc, char *argv[]) exit(EX_OK); } +static void +reset_ctrlr(int argc, char *argv[]) +{ + struct stat devstat; + charpath[64]; + int ch, fd; + + while ((ch = getopt(argc, argv, "")) != -1) { + switch ((char)ch) { + default: + usage(); + } + } + + sprintf(path, "/dev/%s", argv[optind]); + + if (stat(path, &devstat) != 0) { + printf("Invalid device node '%s'.\n", path); + exit(EX_IOERR); + } + + fd = open(path, O_RDWR); + if (fd < 0) { + printf("Could not open %s.\n", path); + exit(EX_NOPERM); + } + + if (ioctl(fd, NVME_RESET_CONTROLLER) == -1) { + printf("ioctl to %s failed.\n", path); + exit(EX_IOERR); + } + + exit(EX_OK); +} + int main(int argc, char *argv[]) { @@ -593,6 +632,8 @@ main(int argc, char *argv[]) identify(argc-1, &argv[1]); else if (strcmp(argv[1], "perftest") == 0) perftest(argc-1, &argv[1]); + else if (strcmp(argv[1], "reset") == 0) + reset_ctrlr(argc-1, &argv[1]); usage(); Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 19:46:51 2013(r248745) +++ head/sys/dev/nvme/nvme.cTue Mar 26 19:50:46 2013(r248746) @@ -255,7 +255,7 @@ nvme_payload_map(void *arg, bus_dma_segm } } - nvme_qpair_submit_cmd(tr->qpair, tr); + nvme_qpair_submit_tracker(tr->qpair, tr); } static int @@ -274,11 +274,
svn commit: r248747 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 19:52:57 2013 New Revision: 248747 URL: http://svnweb.freebsd.org/changeset/base/248747 Log: Add API for nvme consumers to access controller and namespace identify data. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ns.c Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 19:50:46 2013(r248746) +++ head/sys/dev/nvme/nvme.hTue Mar 26 19:52:57 2013(r248747) @@ -740,6 +740,8 @@ voidnvme_unregister_consumer(struct nv /* Controller helper functions */ device_t nvme_ctrlr_get_device(struct nvme_controller *ctrlr); +const struct nvme_controller_data * + nvme_ctrlr_get_data(struct nvme_controller *ctrlr); /* Namespace helper functions */ uint32_t nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns); @@ -749,6 +751,8 @@ uint64_tnvme_ns_get_size(struct nvme_na uint32_t nvme_ns_get_flags(struct nvme_namespace *ns); const char * nvme_ns_get_serial_number(struct nvme_namespace *ns); const char * nvme_ns_get_model_number(struct nvme_namespace *ns); +const struct nvme_namespace_data * + nvme_ns_get_data(struct nvme_namespace *ns); intnvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp, nvme_cb_fn_t cb_fn); Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 19:50:46 2013 (r248746) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 19:52:57 2013 (r248747) @@ -942,3 +942,10 @@ nvme_ctrlr_get_device(struct nvme_contro return (ctrlr->dev); } + +const struct nvme_controller_data * +nvme_ctrlr_get_data(struct nvme_controller *ctrlr) +{ + + return (&ctrlr->cdata); +} Modified: head/sys/dev/nvme/nvme_ns.c == --- head/sys/dev/nvme/nvme_ns.c Tue Mar 26 19:50:46 2013(r248746) +++ head/sys/dev/nvme/nvme_ns.c Tue Mar 26 19:52:57 2013(r248747) @@ -221,6 +221,13 @@ nvme_ns_get_model_number(struct nvme_nam return ((const char *)ns->ctrlr->cdata.mn); } +const struct nvme_namespace_data * +nvme_ns_get_data(struct nvme_namespace *ns) +{ + + return (&ns->data); +} + static void nvme_ns_bio_done(void *arg, const struct nvme_completion *status) { ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248748 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 19:58:17 2013 New Revision: 248748 URL: http://svnweb.freebsd.org/changeset/base/248748 Log: Add handling for controller fatal status (csts.cfs). On any I/O timeout, check for csts.cfs==1. If set, the controller is reporting fatal status and we reset the controller immediately, rather than trying to abort the timed out command. This changeset also includes deferring the controller start portion of the reset to a separate task. This ensures we are always performing a controller start operation from a consistent context. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 19:52:57 2013 (r248747) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 19:58:17 2013 (r248748) @@ -427,7 +427,7 @@ nvme_ctrlr_reset(struct nvme_controller status = nvme_ctrlr_hw_reset(ctrlr); DELAY(100*1000); if (status == 0) - nvme_ctrlr_start(ctrlr); + taskqueue_enqueue(ctrlr->taskqueue, &ctrlr->restart_task); } static int @@ -686,6 +686,14 @@ err: } static void +nvme_ctrlr_restart_task(void *arg, int pending) +{ + struct nvme_controller *ctrlr = arg; + + nvme_ctrlr_start(ctrlr); +} + +static void nvme_ctrlr_intx_handler(void *arg) { struct nvme_controller *ctrlr = arg; @@ -864,6 +872,11 @@ intx: ctrlr->cdev->si_drv1 = (void *)ctrlr; + TASK_INIT(&ctrlr->restart_task, 0, nvme_ctrlr_restart_task, ctrlr); + ctrlr->taskqueue = taskqueue_create("nvme_taskq", M_WAITOK, + taskqueue_thread_enqueue, &ctrlr->taskqueue); + taskqueue_start_threads(&ctrlr->taskqueue, 1, PI_DISK, "nvme taskq"); + return (0); } @@ -872,6 +885,8 @@ nvme_ctrlr_destruct(struct nvme_controll { int i; + taskqueue_free(ctrlr->taskqueue); + for (i = 0; i < NVME_MAX_NAMESPACES; i++) nvme_ns_destruct(&ctrlr->ns[i]); Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 19:52:57 2013 (r248747) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 19:58:17 2013 (r248748) @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -236,6 +237,8 @@ struct nvme_controller { uint32_tns_identified; uint32_tqueues_created; uint32_tnum_start_attempts; + struct task restart_task; + struct taskqueue*taskqueue; /* For shared legacy interrupt. */ int rid; Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 19:52:57 2013 (r248747) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 19:58:17 2013 (r248748) @@ -98,7 +98,7 @@ nvme_qpair_construct_tracker(struct nvme bus_dmamap_load(qpair->dma_tag, tr->prp_dma_map, tr->prp, sizeof(tr->prp), nvme_single_map, &tr->prp_bus_addr, 0); - callout_init_mtx(&tr->timer, &qpair->lock, 0); + callout_init(&tr->timer, 1); tr->cid = cid; tr->qpair = qpair; } @@ -456,8 +456,24 @@ static void nvme_timeout(void *arg) { struct nvme_tracker *tr = arg; + struct nvme_qpair *qpair = tr->qpair; + struct nvme_controller *ctrlr = qpair->ctrlr; + union csts_register csts; - nvme_ctrlr_cmd_abort(tr->qpair->ctrlr, tr->cid, tr->qpair->id, + csts.raw = nvme_mmio_read_4(ctrlr, csts); + if (csts.bits.cfs == 1) { + /* +* The controller is reporting fatal status. Don't bother +* trying to abort the timed out command - proceed +* immediately to a controller-level reset. +*/ + device_printf(ctrlr->dev, + "controller reports fatal status, resetting...\n"); + nvme_ctrlr_reset(ctrlr); + return; + } + + nvme_ctrlr_cmd_abort(ctrlr, tr->cid, qpair->id, nvme_abort_complete, tr); } ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248749 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 20:02:35 2013 New Revision: 248749 URL: http://svnweb.freebsd.org/changeset/base/248749 Log: Add a tunable for the I/O timeout interval. Default is still 30 seconds, but can be adjusted between a min/max of 5 and 120 seconds. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c head/sys/dev/nvme/nvme_sysctl.c Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 19:58:17 2013 (r248748) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 20:02:35 2013 (r248749) @@ -592,10 +592,10 @@ nvme_ctrlr_construct_and_submit_aer(stru aer->req = req; /* -* Override default timeout value here, since asynchronous event -* requests should by nature never be timed out. +* Disable timeout here, since asynchronous event requests should by +* nature never be timed out. */ - req->timeout = 0; + req->timeout = FALSE; req->cmd.opc = NVME_OPC_ASYNC_EVENT_REQUEST; nvme_ctrlr_submit_admin_request(ctrlr, req); } @@ -791,6 +791,7 @@ nvme_ctrlr_construct(struct nvme_control union cap_lo_register cap_lo; union cap_hi_register cap_hi; int num_vectors, per_cpu_io_queues, status = 0; + int timeout_period; ctrlr->dev = dev; ctrlr->is_started = FALSE; @@ -822,6 +823,12 @@ nvme_ctrlr_construct(struct nvme_control cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo); ctrlr->ready_timeout_in_ms = cap_lo.bits.to * 500; + timeout_period = NVME_DEFAULT_TIMEOUT_PERIOD; + TUNABLE_INT_FETCH("hw.nvme.timeout_period", &timeout_period); + timeout_period = min(timeout_period, NVME_MAX_TIMEOUT_PERIOD); + timeout_period = max(timeout_period, NVME_MIN_TIMEOUT_PERIOD); + ctrlr->timeout_period = timeout_period; + per_cpu_io_queues = 1; TUNABLE_INT_FETCH("hw.nvme.per_cpu_io_queues", &per_cpu_io_queues); ctrlr->per_cpu_io_queues = per_cpu_io_queues ? TRUE : FALSE; Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 19:58:17 2013 (r248748) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 20:02:35 2013 (r248749) @@ -100,7 +100,9 @@ MALLOC_DECLARE(M_NVME); #define NVME_MAX_CONSUMERS (2) #define NVME_MAX_ASYNC_EVENTS (8) -#define NVME_TIMEOUT_IN_SEC(30) +#define NVME_DEFAULT_TIMEOUT_PERIOD(30)/* in seconds */ +#define NVME_MIN_TIMEOUT_PERIOD(5) +#define NVME_MAX_TIMEOUT_PERIOD(120) #ifndef CACHE_LINE_SIZE #define CACHE_LINE_SIZE(64) @@ -113,7 +115,7 @@ struct nvme_request { struct nvme_command cmd; void*payload; uint32_tpayload_size; - uint32_ttimeout; + boolean_t timeout; struct uio *uio; nvme_cb_fn_tcb_fn; void*cb_arg; @@ -257,6 +259,9 @@ struct nvme_controller { /** interrupt coalescing threshold */ uint32_tint_coal_threshold; + /** timeout period in seconds */ + uint32_ttimeout_period; + struct nvme_qpair adminq; struct nvme_qpair *ioq; @@ -427,7 +432,7 @@ nvme_allocate_request(void *payload, uin req->payload_size = payload_size; req->cb_fn = cb_fn; req->cb_arg = cb_arg; - req->timeout = NVME_TIMEOUT_IN_SEC; + req->timeout = TRUE; return (req); } @@ -444,7 +449,7 @@ nvme_allocate_request_uio(struct uio *ui req->uio = uio; req->cb_fn = cb_fn; req->cb_arg = cb_arg; - req->timeout = NVME_TIMEOUT_IN_SEC; + req->timeout = TRUE; return (req); } Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 19:58:17 2013 (r248748) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 20:02:35 2013 (r248749) @@ -480,20 +480,23 @@ nvme_timeout(void *arg) void nvme_qpair_submit_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr) { - struct nvme_request *req; + struct nvme_request *req; + struct nvme_controller *ctrlr; mtx_assert(&qpair->lock, MA_OWNED); req = tr->req; req->cmd.cid = tr->cid; qpair->act_tr[tr->cid] = tr; + ctrlr = qpair->ctrlr; - if (req->timeout > 0) + if (req->timeout) #if __FreeBSD_version >= 800030 -
svn commit: r248750 - head/sys/dev/ath
Author: adrian Date: Tue Mar 26 20:04:45 2013 New Revision: 248750 URL: http://svnweb.freebsd.org/changeset/base/248750 Log: Implement the replacement EDMA FIFO code. (Yes, the previous code temporarily broke EDMA TX. I'm sorry; I should've actually setup ATH_BUF_FIFOEND on frames so txq->axq_fifo_depth was cleared!) This code implements a whole bunch of sorely needed EDMA TX improvements along with CABQ TX support. The specifics: * When filling/refilling the FIFO, use the new TXQ staging queue for FIFO frames * Tag frames with ATH_BUF_FIFOPTR and ATH_BUF_FIFOEND correctly. For now the non-CABQ transmit path pushes one frame into the TXQ staging queue without setting up the intermediary link pointers to chain them together, so draining frames from the txq staging queue to the FIFO queue occurs AMPDU / MPDU at a time. * In the CABQ case, manually tag the list with ATH_BUF_FIFOPTR and ATH_BUF_FIFOEND so a chain of frames is pushed into the FIFO at once. * Now that frames are in a FIFO pending queue, we can top up the FIFO after completing a single frame. This means we can keep it filled rather than waiting for it drain and _then_ adding more frames. * The EDMA restart routine now walks the FIFO queue in the TXQ rather than the pending queue and re-initialises the FIFO with that. * When restarting EDMA, we may have partially completed sending a list. So stamp the first frame that we see in a list with ATH_BUF_FIFOPTR and push _that_ into the hardware. * When completing frames, only check those on the FIFO queue. We should never ever queue frames from the pending queue direct to the hardware, so there's no point in checking. * Until I figure out what's going on, make sure if the TXSTATUS for an empty queue pops up, complain loudly and continue. This will stop the panics that people are seeing. I'll add some code later which will assist in ensuring I'm populating each descriptor with the correct queue ID. * When considering whether to queue frames to the hardware queue directly or software queue frames, make sure the depth of the FIFO is taken into account now. * When completing frames, tag them with ATH_BUF_BUSY if they're not the final frame in a FIFO list. The same holding descriptor behaviour is required when handling descriptors linked together with a link pointer as the hardware will re-read the previous descriptor to refresh the link pointer before contiuning. * .. and if we complete the FIFO list (ie, the buffer has ATH_BUF_FIFOEND set), then we don't need the holding buffer any longer. Thus, free it. Tested: * AR9380/AR9580, STA and hostap * AR9280, STA/hostap TODO: * I don't yet trust that the EDMA restart routine is totally correct in all circumstances. I'll continue to thrash this out under heavy multiple-TXQ traffic load and fix whatever pops up. Modified: head/sys/dev/ath/if_ath_beacon.c head/sys/dev/ath/if_ath_tx.c head/sys/dev/ath/if_ath_tx_edma.c Modified: head/sys/dev/ath/if_ath_beacon.c == --- head/sys/dev/ath/if_ath_beacon.cTue Mar 26 20:02:35 2013 (r248749) +++ head/sys/dev/ath/if_ath_beacon.cTue Mar 26 20:04:45 2013 (r248750) @@ -474,6 +474,10 @@ ath_beacon_proc(void *arg, int pending) vap = sc->sc_bslot[slot]; if (vap != NULL && vap->iv_state >= IEEE80211_S_RUN) { bf = ath_beacon_generate(sc, vap); + /* +* XXX TODO: this should use settxdesclinkptr() +* otherwise it won't work for EDMA chipsets! +*/ if (bf != NULL) { /* XXX should do this using the ds */ *bflink = bf->bf_daddr; @@ -482,6 +486,10 @@ ath_beacon_proc(void *arg, int pending) } } } + /* +* XXX TODO: this should use settxdesclinkptr() +* otherwise it won't work for EDMA chipsets! +*/ *bflink = 0;/* terminate list */ } @@ -540,17 +548,99 @@ ath_beacon_proc(void *arg, int pending) } } -/* - * Start CABQ transmission - this assumes that all frames are prepped - * and ready in the CABQ. - * - * XXX TODO: methodize this; for the EDMA case it should only push - * into the hardware if the FIFO isn't full _AND_ then it should - * tag the final buffer in the queue as ATH_BUF_FIFOEND so the FIFO - * depth is correctly accounted for. - */ -void -ath_beacon_cabq_start(struct ath_softc *sc) +static void +
svn commit: r248751 - head/share/mk
Author: emaste Date: Tue Mar 26 20:11:09 2013 New Revision: 248751 URL: http://svnweb.freebsd.org/changeset/base/248751 Log: Unconditionally include ${SRCCONF} if overridden This avoids silently failing to include ${SRCCONF} specified by a make(1) invocation. Modified: head/share/mk/bsd.own.mk Modified: head/share/mk/bsd.own.mk == --- head/share/mk/bsd.own.mkTue Mar 26 20:04:45 2013(r248750) +++ head/share/mk/bsd.own.mkTue Mar 26 20:11:09 2013(r248751) @@ -117,7 +117,7 @@ : .if !defined(_WITHOUT_SRCCONF) SRCCONF?= /etc/src.conf -.if exists(${SRCCONF}) +.if exists(${SRCCONF}) || ${SRCCONF} != "/etc/src.conf" .include "${SRCCONF}" .endif .endif ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248752 - in head: cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers sys/cddl/contrib/opensolaris/uts/common/dtrace
Author: pfg Date: Tue Mar 26 20:17:08 2013 New Revision: 248752 URL: http://svnweb.freebsd.org/changeset/base/248752 Log: Dtrace: dtrace.c erroneously checks for memory alignment on amd64. Merge change from illumos: 3511 dtrace.c erroneously checks for memory alignment on amd64 Illumos Revision: c93cc65 Reference: https://www.illumos.org/issues/3511 Obtained from:Illumos MFC after:3 weeks Modified: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Modified: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d == --- head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d Tue Mar 26 20:11:09 2013(r248751) +++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d Tue Mar 26 20:17:08 2013(r248752) @@ -24,7 +24,9 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2012 by Delphix. All rights reserved. + */ /* * ASSERTION: @@ -32,44 +34,51 @@ * a runtime error. * * SECTION: Pointers and Arrays/Generic Pointers - * - * NOTES: - * This test doesn't apply to x86; for the time being, we're working - * around this with the preprocessor. */ #pragma D option quiet -int array[3]; -uintptr_t uptr; +#if defined(__i386) || defined(__amd64) +#define __x86 1 +#endif + +int array[2]; +char *ptr; int *p; int *q; int *r; BEGIN { -#ifdef __i386 + array[0] = 0x12345678; + array[1] = 0xabcdefff; + + ptr = (char *) &array[0]; + + p = (int *) (ptr); + q = (int *) (ptr + 2); + r = (int *) (ptr + 3); + + printf("*p: 0x%x\n", *p); + printf("*q: 0x%x\n", *q); + printf("*r: 0x%x\n", *r); + + /* +* On x86, the above unaligned memory accesses are allowed and should +* not result in the ERROR probe firing. +*/ +#ifdef __x86 exit(1); #else - array[0] = 20; - array[1] = 40; - array[2] = 80; - - uptr = (uintptr_t) &array[0]; - - p = (int *) (uptr); - q = (int *) (uptr + 2); - r = (int *) (uptr + 3); - - printf("array[0]: %d\t*p: %d\n", array[0], *p); - printf("array[1]: %d\t*q: %d\n", array[1], *q); - printf("array[2]: %d\t*r: %d\n", array[2], *r); - exit(0); #endif } ERROR { +#ifdef __x86 + exit(0); +#else exit(1); +#endif } Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c == --- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.cTue Mar 26 20:11:09 2013(r248751) +++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.cTue Mar 26 20:17:08 2013(r248752) @@ -443,7 +443,7 @@ static kmutex_t dtrace_errlock; #defineDTRACE_STORE(type, tomax, offset, what) \ *((type *)((uintptr_t)(tomax) + (uintptr_t)offset)) = (type)(what); -#ifndef __i386 +#ifndef __x86 #defineDTRACE_ALIGNCHECK(addr, size, flags) \ if (addr & (size - 1)) {\ *flags |= CPU_DTRACE_BADALIGN; \ ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248753 - head/share/mk
Author: emaste Date: Tue Mar 26 20:32:46 2013 New Revision: 248753 URL: http://svnweb.freebsd.org/changeset/base/248753 Log: Always define and use PROGNAME This avoids having separate cases in the install rule for PROGNAME set and not set. This is a minor cleanup in advance of further support for standalone debug files. Modified: head/share/mk/bsd.prog.mk Modified: head/share/mk/bsd.prog.mk == --- head/share/mk/bsd.prog.mk Tue Mar 26 20:17:08 2013(r248752) +++ head/share/mk/bsd.prog.mk Tue Mar 26 20:32:46 2013(r248753) @@ -41,6 +41,7 @@ PROG= ${PROG_CXX} .endif .if defined(PROG) +PROGNAME?= ${PROG} .if defined(SRCS) OBJS+= ${SRCS:N*.h:R:S/$/.o/g} @@ -153,13 +154,8 @@ realinstall: _proginstall .ORDER: beforeinstall _proginstall _proginstall: .if defined(PROG) -.if defined(PROGNAME) ${INSTALL} ${STRIP} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ ${_INSTALLFLAGS} ${PROG} ${DESTDIR}${BINDIR}/${PROGNAME} -.else - ${INSTALL} ${STRIP} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ - ${_INSTALLFLAGS} ${PROG} ${DESTDIR}${BINDIR} -.endif .endif .endif # !target(realinstall) ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248754 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 20:32:57 2013 New Revision: 248754 URL: http://svnweb.freebsd.org/changeset/base/248754 Log: By default, always escalate to controller reset when an I/O times out. While aborts are typically cleaner than a full controller reset, many times an I/O timeout indicates other controller-level issues where aborts may not work. NVMe drivers for other operating systems are also defaulting to controller reset rather than aborts for timed out I/O. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 20:32:46 2013 (r248753) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 20:32:57 2013 (r248754) @@ -422,12 +422,8 @@ nvme_ctrlr_hw_reset(struct nvme_controll void nvme_ctrlr_reset(struct nvme_controller *ctrlr) { - int status; - status = nvme_ctrlr_hw_reset(ctrlr); - DELAY(100*1000); - if (status == 0) - taskqueue_enqueue(ctrlr->taskqueue, &ctrlr->restart_task); + taskqueue_enqueue(ctrlr->taskqueue, &ctrlr->reset_task); } static int @@ -686,11 +682,24 @@ err: } static void -nvme_ctrlr_restart_task(void *arg, int pending) +nvme_ctrlr_reset_task(void *arg, int pending) { - struct nvme_controller *ctrlr = arg; + struct nvme_controller *ctrlr = arg; + int status; - nvme_ctrlr_start(ctrlr); + device_printf(ctrlr->dev, "resetting controller"); + status = nvme_ctrlr_hw_reset(ctrlr); + /* +* Use pause instead of DELAY, so that we yield to any nvme interrupt +* handlers on this CPU that were blocked on a qpair lock. We want +* all nvme interrupts completed before proceeding with restarting the +* controller. +* +* XXX - any way to guarantee the interrupt handlers have quiesced? +*/ + pause("nvmereset", hz / 10); + if (status == 0) + nvme_ctrlr_start(ctrlr); } static void @@ -841,6 +850,9 @@ nvme_ctrlr_construct(struct nvme_control ctrlr->force_intx = 0; TUNABLE_INT_FETCH("hw.nvme.force_intx", &ctrlr->force_intx); + ctrlr->enable_aborts = 0; + TUNABLE_INT_FETCH("hw.nvme.enable_aborts", &ctrlr->enable_aborts); + ctrlr->msix_enabled = 1; if (ctrlr->force_intx) { @@ -879,7 +891,7 @@ intx: ctrlr->cdev->si_drv1 = (void *)ctrlr; - TASK_INIT(&ctrlr->restart_task, 0, nvme_ctrlr_restart_task, ctrlr); + TASK_INIT(&ctrlr->reset_task, 0, nvme_ctrlr_reset_task, ctrlr); ctrlr->taskqueue = taskqueue_create("nvme_taskq", M_WAITOK, taskqueue_thread_enqueue, &ctrlr->taskqueue); taskqueue_start_threads(&ctrlr->taskqueue, 1, PI_DISK, "nvme taskq"); Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 20:32:46 2013 (r248753) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 20:32:57 2013 (r248754) @@ -230,6 +230,7 @@ struct nvme_controller { uint32_tmsix_enabled; uint32_tforce_intx; + uint32_tenable_aborts; uint32_tnum_io_queues; boolean_t per_cpu_io_queues; @@ -239,7 +240,7 @@ struct nvme_controller { uint32_tns_identified; uint32_tqueues_created; uint32_tnum_start_attempts; - struct task restart_task; + struct task reset_task; struct taskqueue*taskqueue; /* For shared legacy interrupt. */ Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 20:32:46 2013 (r248753) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 20:32:57 2013 (r248754) @@ -460,21 +460,20 @@ nvme_timeout(void *arg) struct nvme_controller *ctrlr = qpair->ctrlr; union csts_register csts; + /* Read csts to get value of cfs - controller fatal status. */ csts.raw = nvme_mmio_read_4(ctrlr, csts); - if (csts.bits.cfs == 1) { + device_printf(ctrlr->dev, "i/o timeout, csts.cfs=%d\n", csts.bits.cfs); + nvme_dump_command(&tr->req->cmd); + + if (ctrlr->enable_aborts && csts.bits.cfs == 0) { /* -* The controller is reporting fatal status. Don't bother -* trying to abort the timed out command - proceed -* immediately to a controller-level reset. +* If aborts are enabled, only use them if the c
svn commit: r248755 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 20:56:58 2013 New Revision: 248755 URL: http://svnweb.freebsd.org/changeset/base/248755 Log: Make nvme_ctrlr_reset a nop if a reset is already in progress. This protects against cases where a controller crashes with multiple I/O outstanding, each timing out and requesting controller resets simultaneously. While here, remove a debugging printf from a previous commit, and add more logging around I/O that need to be resubmitted after a controller reset. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 20:32:57 2013 (r248754) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 20:56:58 2013 (r248755) @@ -422,6 +422,13 @@ nvme_ctrlr_hw_reset(struct nvme_controll void nvme_ctrlr_reset(struct nvme_controller *ctrlr) { + int cmpset; + + cmpset = atomic_cmpset_32(&ctrlr->is_resetting, 0, 1); + + if (cmpset == 0) + /* Controller is already resetting. */ + return; taskqueue_enqueue(ctrlr->taskqueue, &ctrlr->reset_task); } @@ -700,6 +707,8 @@ nvme_ctrlr_reset_task(void *arg, int pen pause("nvmereset", hz / 10); if (status == 0) nvme_ctrlr_start(ctrlr); + + atomic_cmpset_32(&ctrlr->is_resetting, 1, 0); } static void @@ -896,6 +905,8 @@ intx: taskqueue_thread_enqueue, &ctrlr->taskqueue); taskqueue_start_threads(&ctrlr->taskqueue, 1, PI_DISK, "nvme taskq"); + ctrlr->is_resetting = 0; + return (0); } Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 20:32:57 2013 (r248754) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 20:56:58 2013 (r248755) @@ -100,7 +100,7 @@ MALLOC_DECLARE(M_NVME); #define NVME_MAX_CONSUMERS (2) #define NVME_MAX_ASYNC_EVENTS (8) -#define NVME_DEFAULT_TIMEOUT_PERIOD(30)/* in seconds */ +#define NVME_DEFAULT_TIMEOUT_PERIOD(30)/* in seconds */ #define NVME_MIN_TIMEOUT_PERIOD(5) #define NVME_MAX_TIMEOUT_PERIOD(120) @@ -280,6 +280,8 @@ struct nvme_controller { void*cons_cookie[NVME_MAX_CONSUMERS]; + uint32_tis_resetting; + #ifdef CHATHAM2 uint64_tchatham_size; uint64_tchatham_lbas; Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 20:32:57 2013 (r248754) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 20:56:58 2013 (r248755) @@ -142,7 +142,13 @@ nvme_qpair_complete_tracker(struct nvme_ TAILQ_REMOVE(&qpair->outstanding_tr, tr, tailq); TAILQ_INSERT_HEAD(&qpair->free_tr, tr, tailq); - if (!STAILQ_EMPTY(&qpair->queued_req)) { + /* +* If the controller is in the middle of resetting, don't +* try to submit queued requests here - let the reset logic +* handle that instead. +*/ + if (!STAILQ_EMPTY(&qpair->queued_req) && + !qpair->ctrlr->is_resetting) { req = STAILQ_FIRST(&qpair->queued_req); STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq); _nvme_qpair_submit_request(qpair, req); @@ -462,8 +468,6 @@ nvme_timeout(void *arg) /* Read csts to get value of cfs - controller fatal status. */ csts.raw = nvme_mmio_read_4(ctrlr, csts); - device_printf(ctrlr->dev, "i/o timeout, csts.cfs=%d\n", csts.bits.cfs); - nvme_dump_command(&tr->req->cmd); if (ctrlr->enable_aborts && csts.bits.cfs == 0) { /* @@ -606,8 +610,12 @@ nvme_io_qpair_enable(struct nvme_qpair * nvme_qpair_enable(qpair); - TAILQ_FOREACH(tr, &qpair->outstanding_tr, tailq) + TAILQ_FOREACH(tr, &qpair->outstanding_tr, tailq) { + device_printf(qpair->ctrlr->dev, + "resubmitting outstanding i/o\n"); + nvme_dump_command(&tr->req->cmd); nvme_qpair_submit_tracker(qpair, tr); + } STAILQ_INIT(&temp); STAILQ_SWAP(&qpair->queued_req, &temp, nvme_request); @@ -615,6 +623,9 @@ nvme_io_qpair_enable(struct nvme_qpair * while (!STAILQ_EMPTY(&temp)) { req = STAILQ_FIRST(&temp); STAILQ_REMOVE_HEAD(&temp, stailq); + device_printf(qpair->ctrlr->dev, + "resubmitting queued i/o\n"); +
svn commit: r248756 - in head/sys/dev: nvd nvme
Author: jimharris Date: Tue Mar 26 21:00:18 2013 New Revision: 248756 URL: http://svnweb.freebsd.org/changeset/base/248756 Log: Create struct nvme_status. NVMe error log entries include status, so breaking this out into its own data structure allows it to be included in both the nvme_completion data structure as well as error log entry data structures. While here, expose nvme_completion_is_error(), and change all of the places that were explicitly looking at sc/sct bits to use this macro instead. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvd/nvd.c head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ns.c head/sys/dev/nvme/nvme_qpair.c head/sys/dev/nvme/nvme_test.c head/sys/dev/nvme/nvme_uio.c Modified: head/sys/dev/nvd/nvd.c == --- head/sys/dev/nvd/nvd.c Tue Mar 26 20:56:58 2013(r248755) +++ head/sys/dev/nvd/nvd.c Tue Mar 26 21:00:18 2013(r248756) @@ -153,7 +153,7 @@ nvd_ioctl(struct disk *ndisk, u_long cmd } static void -nvd_done(void *arg, const struct nvme_completion *status) +nvd_done(void *arg, const struct nvme_completion *cpl) { struct bio *bp; struct nvd_disk *ndisk; @@ -168,7 +168,7 @@ nvd_done(void *arg, const struct nvme_co * TODO: add more extensive translation of NVMe status codes * to different bio error codes (i.e. EIO, EINVAL, etc.) */ - if (status->sf_sc || status->sf_sct) { + if (nvme_completion_is_error(cpl)) { bp->bio_error = EIO; bp->bio_flags |= BIO_ERROR; bp->bio_resid = bp->bio_bcount; Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 20:56:58 2013(r248755) +++ head/sys/dev/nvme/nvme.cTue Mar 26 21:00:18 2013(r248756) @@ -223,8 +223,8 @@ nvme_dump_completion(struct nvme_complet printf("cdw0:%08x sqhd:%04x sqid:%04x " "cid:%04x p:%x sc:%02x sct:%x m:%x dnr:%x\n", cpl->cdw0, cpl->sqhd, cpl->sqid, - cpl->cid, cpl->p, cpl->sf_sc, cpl->sf_sct, cpl->sf_m, - cpl->sf_dnr); + cpl->cid, cpl->status.p, cpl->status.sc, cpl->status.sct, + cpl->status.m, cpl->status.dnr); } void Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 20:56:58 2013(r248755) +++ head/sys/dev/nvme/nvme.hTue Mar 26 21:00:18 2013(r248756) @@ -223,26 +223,31 @@ struct nvme_command uint32_t cdw15; /* command-specific */ } __packed; +struct nvme_status { + + uint16_t p : 1; /* phase tag */ + uint16_t sc : 8; /* status code */ + uint16_t sct: 3; /* status code type */ + uint16_t rsvd2 : 2; + uint16_t m : 1; /* more */ + uint16_t dnr: 1; /* do not retry */ +} __packed; + struct nvme_completion { /* dword 0 */ - uint32_t cdw0; /* command-specific */ + uint32_tcdw0; /* command-specific */ /* dword 1 */ - uint32_t rsvd1; + uint32_trsvd1; /* dword 2 */ - uint16_t sqhd; /* submission queue head pointer */ - uint16_t sqid; /* submission queue identifier */ + uint16_tsqhd; /* submission queue head pointer */ + uint16_tsqid; /* submission queue identifier */ /* dword 3 */ - uint16_t cid; /* command identifier */ - uint16_t p : 1; /* phase tag */ - uint16_t sf_sc : 8; /* status field - status code */ - uint16_t sf_sct : 3; /* status field - status code type */ - uint16_t rsvd2 : 2; - uint16_t sf_m : 1; /* status field - more */ - uint16_t sf_dnr : 1; /* status field - do not retry */ + uint16_tcid;/* command identifier */ + struct nvme_status status; } __packed; struct nvme_dsm_range { @@ -686,6 +691,9 @@ enum nvme_io_test_flags { NVME_TEST_FLAG_REFTHREAD = 0x1, }; +#define nvme_completion_is_error(cpl) \ + ((cpl)->status.sc != 0 || (cpl)->status.sct != 0) + #ifdef _KERNEL struct bio; Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 20:56:58 2013 (r248755) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:00:18 2013 (r248756) @@ -447,7 +447,7 @@ nvme_ctrlr_identify(struct nvme_controll nvme_ctrlr_cb, &cpl); status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); mtx_unlock
svn commit: r248757 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:01:53 2013 New Revision: 248757 URL: http://svnweb.freebsd.org/changeset/base/248757 Log: Add structure definitions and a controller command function for error log pages. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr_cmd.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 21:00:18 2013(r248756) +++ head/sys/dev/nvme/nvme.hTue Mar 26 21:01:53 2013(r248757) @@ -622,6 +622,19 @@ enum nvme_log_page { /* 0xC0-0xFF - vendor specific */ }; +struct nvme_error_information_entry { + + uint64_terror_count; + uint16_tsqid; + uint16_tcid; + struct nvme_status status; + uint16_terror_location; + uint64_tlba; + uint32_tnsid; + uint8_t vendor_specific; + uint8_t reserved[35]; +} __packed __aligned(4); + union nvme_critical_warning_state { uint8_t raw; Modified: head/sys/dev/nvme/nvme_ctrlr_cmd.c == --- head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 21:00:18 2013 (r248756) +++ head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 21:01:53 2013 (r248757) @@ -267,6 +267,25 @@ nvme_ctrlr_cmd_get_log_page(struct nvme_ nvme_ctrlr_submit_admin_request(ctrlr, req); } +void +nvme_ctrlr_cmd_get_error_page(struct nvme_controller *ctrlr, +struct nvme_error_information_entry *payload, uint32_t num_entries, +nvme_cb_fn_t cb_fn, void *cb_arg) +{ + + KASSERT(num_entries > 0, ("%s called with num_entries==0\n", __func__)); + + /* Controller's error log page entries is 0-based. */ + if (num_entries > (ctrlr->cdata.elpe + 1)) { + printf("%s num_entries=%d cdata.elpe=%d\n", + __func__, num_entries, ctrlr->cdata.elpe); + num_entries = ctrlr->cdata.elpe + 1; + } + + nvme_ctrlr_cmd_get_log_page(ctrlr, NVME_LOG_ERROR, + NVME_GLOBAL_NAMESPACE_TAG, payload, sizeof(*payload) * num_entries, + cb_fn, cb_arg); +} void nvme_ctrlr_cmd_get_health_information_page(struct nvme_controller *ctrlr, Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 21:00:18 2013 (r248756) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 21:01:53 2013 (r248757) @@ -342,6 +342,11 @@ void nvme_ctrlr_cmd_set_interrupt_coales uint32_t threshold, nvme_cb_fn_t cb_fn, void *cb_arg); +void nvme_ctrlr_cmd_get_error_page(struct nvme_controller *ctrlr, + struct nvme_error_information_entry *payload, + uint32_t num_entries, /* 0 = max */ + nvme_cb_fn_t cb_fn, + void *cb_arg); void nvme_ctrlr_cmd_get_health_information_page(struct nvme_controller *ctrlr, uint32_t nsid, struct nvme_health_information_page *payload, ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248758 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:03:03 2013 New Revision: 248758 URL: http://svnweb.freebsd.org/changeset/base/248758 Log: Add structure definitions and controller command function for firmware log pages. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr_cmd.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 21:01:53 2013(r248757) +++ head/sys/dev/nvme/nvme.hTue Mar 26 21:03:03 2013(r248758) @@ -682,6 +682,18 @@ struct nvme_health_information_page { uint8_t reserved2[320]; } __packed __aligned(4); +struct nvme_firmware_page { + + struct { + uint8_t slot: 3; /* slot for current FW */ + uint8_t reserved: 5; + } __packed afi; + + uint8_t reserved[7]; + uint64_trevision[7]; /* revisions for 7 slots */ + uint8_t reserved2[448]; +} __packed __aligned(4); + #define NVME_TEST_MAX_THREADS 128 struct nvme_io_test { Modified: head/sys/dev/nvme/nvme_ctrlr_cmd.c == --- head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 21:01:53 2013 (r248757) +++ head/sys/dev/nvme/nvme_ctrlr_cmd.c Tue Mar 26 21:03:03 2013 (r248758) @@ -298,6 +298,16 @@ nvme_ctrlr_cmd_get_health_information_pa } void +nvme_ctrlr_cmd_get_firmware_page(struct nvme_controller *ctrlr, +struct nvme_firmware_page *payload, nvme_cb_fn_t cb_fn, void *cb_arg) +{ + + nvme_ctrlr_cmd_get_log_page(ctrlr, NVME_LOG_FIRMWARE_SLOT, + NVME_GLOBAL_NAMESPACE_TAG, payload, sizeof(*payload), cb_fn, + cb_arg); +} + +void nvme_ctrlr_cmd_abort(struct nvme_controller *ctrlr, uint16_t cid, uint16_t sqid, nvme_cb_fn_t cb_fn, void *cb_arg) { Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 21:01:53 2013 (r248757) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 21:03:03 2013 (r248758) @@ -352,6 +352,10 @@ void nvme_ctrlr_cmd_get_health_informati struct nvme_health_information_page *payload, nvme_cb_fn_t cb_fn, void *cb_arg); +void nvme_ctrlr_cmd_get_firmware_page(struct nvme_controller *ctrlr, +struct nvme_firmware_page *payload, +nvme_cb_fn_t cb_fn, +void *cb_arg); void nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr, struct nvme_qpair *io_que, uint16_t vector, nvme_cb_fn_t cb_fn, void *cb_arg); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248759 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:05:15 2013 New Revision: 248759 URL: http://svnweb.freebsd.org/changeset/base/248759 Log: When an asynchronous event request is completed, automatically fetch the specified log page. This satisfies the spec condition that future async events of the same type will not be sent until the associated log page is fetched. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:03:03 2013 (r248758) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:05:15 2013 (r248759) @@ -557,10 +557,65 @@ nvme_ctrlr_construct_namespaces(struct n return (0); } +static boolean_t +is_log_page_id_valid(uint8_t page_id) +{ + + switch (page_id) { + case NVME_LOG_ERROR: + case NVME_LOG_HEALTH_INFORMATION: + case NVME_LOG_FIRMWARE_SLOT: + return (TRUE); + } + + return (FALSE); +} + +static uint32_t +nvme_ctrlr_get_log_page_size(struct nvme_controller *ctrlr, uint8_t page_id) +{ + uint32_tlog_page_size; + + switch (page_id) { + case NVME_LOG_ERROR: + log_page_size = min( + sizeof(struct nvme_error_information_entry) * + ctrlr->cdata.elpe, + NVME_MAX_AER_LOG_SIZE); + break; + case NVME_LOG_HEALTH_INFORMATION: + log_page_size = sizeof(struct nvme_health_information_page); + break; + case NVME_LOG_FIRMWARE_SLOT: + log_page_size = sizeof(struct nvme_firmware_page); + break; + default: + log_page_size = 0; + break; + } + + return (log_page_size); +} + +static void +nvme_ctrlr_async_event_log_page_cb(void *arg, const struct nvme_completion *cpl) +{ + struct nvme_async_event_request *aer = arg; + + nvme_notify_async_consumers(aer->ctrlr, &aer->cpl); + + /* +* Repost another asynchronous event request to replace the one +* that just completed. +*/ + nvme_ctrlr_construct_and_submit_aer(aer->ctrlr, aer); +} + static void nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl) { - struct nvme_async_event_request *aer = arg; + struct nvme_async_event_request *aer = arg; + uint8_t log_page_id; if (cpl->status.sc == NVME_SC_ABORTED_SQ_DELETION) { /* @@ -572,16 +627,29 @@ nvme_ctrlr_async_event_cb(void *arg, con return; } - nvme_notify_async_consumers(aer->ctrlr, cpl); + printf("Asynchronous event occurred.\n"); - /* TODO: decode async event type based on status */ + /* Associated log page is in bits 23:16 of completion entry dw0. */ + log_page_id = (cpl->cdw0 & 0xFF) >> 16; - /* -* Repost another asynchronous event request to replace the one that -* just completed. -*/ - printf("Asynchronous event occurred.\n"); - nvme_ctrlr_construct_and_submit_aer(aer->ctrlr, aer); + if (is_log_page_id_valid(log_page_id)) { + aer->log_page_size = nvme_ctrlr_get_log_page_size(aer->ctrlr, + log_page_id); + memcpy(&aer->cpl, cpl, sizeof(*cpl)); + nvme_ctrlr_cmd_get_log_page(aer->ctrlr, log_page_id, + NVME_GLOBAL_NAMESPACE_TAG, aer->log_page_buffer, + aer->log_page_size, nvme_ctrlr_async_event_log_page_cb, + aer); + /* Wait to notify consumers until after log page is fetched. */ + } else { + nvme_notify_async_consumers(aer->ctrlr, cpl); + + /* +* Repost another asynchronous event request to replace the one +* that just completed. +*/ + nvme_ctrlr_construct_and_submit_aer(aer->ctrlr, aer); + } } static void Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 21:03:03 2013 (r248758) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 21:05:15 2013 (r248759) @@ -104,6 +104,9 @@ MALLOC_DECLARE(M_NVME); #define NVME_MIN_TIMEOUT_PERIOD(5) #define NVME_MAX_TIMEOUT_PERIOD(120) +/* Maximum log page size to fetch for AERs. */ +#define NVME_MAX_AER_LOG_SIZE (4096) + #ifndef CACHE_LINE_SIZE #define CACHE_LINE_SIZE(64) #endif @@ -126,6 +129,9 @@ struct nvme_async_event_request { struct nvme_controller *ctrlr; struct nvme_request *req; + struct nvme_completion cpl; +
svn commit: r248760 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:08:32 2013 New Revision: 248760 URL: http://svnweb.freebsd.org/changeset/base/248760 Log: Pass associated log page data to async event consumers, if requested. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 21:05:15 2013(r248759) +++ head/sys/dev/nvme/nvme.cTue Mar 26 21:08:32 2013(r248760) @@ -331,7 +331,9 @@ nvme_notify_consumer(struct nvme_consume void nvme_notify_async_consumers(struct nvme_controller *ctrlr, - const struct nvme_completion *async_cpl) + const struct nvme_completion *async_cpl, + uint32_t log_page_id, void *log_page_buffer, + uint32_t log_page_size) { struct nvme_consumer*cons; uint32_ti; @@ -339,7 +341,8 @@ nvme_notify_async_consumers(struct nvme_ for (i = 0; i < NVME_MAX_CONSUMERS; i++) { cons = &nvme_consumer[i]; if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL) - (*cons->async_fn)(ctrlr->cons_cookie[i], async_cpl); + (*cons->async_fn)(ctrlr->cons_cookie[i], async_cpl, + log_page_id, log_page_buffer, log_page_size); } } Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 21:05:15 2013(r248759) +++ head/sys/dev/nvme/nvme.hTue Mar 26 21:08:32 2013(r248760) @@ -731,7 +731,8 @@ typedef void (*nvme_cb_fn_t)(void *, con typedef void *(*nvme_cons_ns_fn_t)(struct nvme_namespace *, void *); typedef void *(*nvme_cons_ctrlr_fn_t)(struct nvme_controller *); -typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *); +typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *, +uint32_t, void *, uint32_t); enum nvme_namespace_flags { NVME_NS_DEALLOCATE_SUPPORTED= 0x1, Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:05:15 2013 (r248759) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:08:32 2013 (r248760) @@ -602,7 +602,21 @@ nvme_ctrlr_async_event_log_page_cb(void { struct nvme_async_event_request *aer = arg; - nvme_notify_async_consumers(aer->ctrlr, &aer->cpl); + /* +* If the log page fetch for some reason completed with an error, +* don't pass log page data to the consumers. In practice, this case +* should never happen. +*/ + if (nvme_completion_is_error(cpl)) + nvme_notify_async_consumers(aer->ctrlr, &aer->cpl, + aer->log_page_id, NULL, 0); + else + /* +* Pass the cpl data from the original async event completion, +* not the log page fetch. +*/ + nvme_notify_async_consumers(aer->ctrlr, &aer->cpl, + aer->log_page_id, aer->log_page_buffer, aer->log_page_size); /* * Repost another asynchronous event request to replace the one @@ -615,7 +629,6 @@ static void nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl) { struct nvme_async_event_request *aer = arg; - uint8_t log_page_id; if (cpl->status.sc == NVME_SC_ABORTED_SQ_DELETION) { /* @@ -630,19 +643,20 @@ nvme_ctrlr_async_event_cb(void *arg, con printf("Asynchronous event occurred.\n"); /* Associated log page is in bits 23:16 of completion entry dw0. */ - log_page_id = (cpl->cdw0 & 0xFF) >> 16; + aer->log_page_id = (cpl->cdw0 & 0xFF) >> 16; - if (is_log_page_id_valid(log_page_id)) { + if (is_log_page_id_valid(aer->log_page_id)) { aer->log_page_size = nvme_ctrlr_get_log_page_size(aer->ctrlr, - log_page_id); + aer->log_page_id); memcpy(&aer->cpl, cpl, sizeof(*cpl)); - nvme_ctrlr_cmd_get_log_page(aer->ctrlr, log_page_id, + nvme_ctrlr_cmd_get_log_page(aer->ctrlr, aer->log_page_id, NVME_GLOBAL_NAMESPACE_TAG, aer->log_page_buffer, aer->log_page_size, nvme_ctrlr_async_event_log_page_cb, aer); /* Wait to notify consumers until after log page is fetched. */ } else { - nvme_notify_async_consumers(aer->ctrlr, cpl); + nvme_notify_as
svn commit: r248761 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:14:51 2013 New Revision: 248761 URL: http://svnweb.freebsd.org/changeset/base/248761 Log: Cap the number of retry attempts to a configurable number. This ensures that if a specific I/O repeatedly times out, we don't retry it indefinitely. The default number of retries will be 4, but is adjusted using hw.nvme.retry_count. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 21:08:32 2013(r248760) +++ head/sys/dev/nvme/nvme.cTue Mar 26 21:14:51 2013(r248761) @@ -49,7 +49,8 @@ struct nvme_consumer { struct nvme_consumer nvme_consumer[NVME_MAX_CONSUMERS]; #defineINVALID_CONSUMER_ID 0x -uma_zone_t nvme_request_zone; +uma_zone_t nvme_request_zone; +int32_tnvme_retry_count; MALLOC_DEFINE(M_NVME, "nvme", "nvme(4) memory allocations"); Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:08:32 2013 (r248760) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:14:51 2013 (r248761) @@ -731,6 +731,10 @@ nvme_ctrlr_start(void *ctrlr_arg) struct nvme_controller *ctrlr = ctrlr_arg; int i; + nvme_qpair_reset(&ctrlr->adminq); + for (i = 0; i < ctrlr->num_io_queues; i++) + nvme_qpair_reset(&ctrlr->ioq[i]); + nvme_admin_qpair_enable(&ctrlr->adminq); if (nvme_ctrlr_identify(ctrlr) != 0) @@ -929,6 +933,9 @@ nvme_ctrlr_construct(struct nvme_control timeout_period = max(timeout_period, NVME_MIN_TIMEOUT_PERIOD); ctrlr->timeout_period = timeout_period; + nvme_retry_count = NVME_DEFAULT_RETRY_COUNT; + TUNABLE_INT_FETCH("hw.nvme.retry_count", &nvme_retry_count); + per_cpu_io_queues = 1; TUNABLE_INT_FETCH("hw.nvme.per_cpu_io_queues", &per_cpu_io_queues); ctrlr->per_cpu_io_queues = per_cpu_io_queues ? TRUE : FALSE; Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 21:08:32 2013 (r248760) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 21:14:51 2013 (r248761) @@ -104,6 +104,8 @@ MALLOC_DECLARE(M_NVME); #define NVME_MIN_TIMEOUT_PERIOD(5) #define NVME_MAX_TIMEOUT_PERIOD(120) +#define NVME_DEFAULT_RETRY_COUNT (4) + /* Maximum log page size to fetch for AERs. */ #define NVME_MAX_AER_LOG_SIZE (4096) @@ -111,7 +113,8 @@ MALLOC_DECLARE(M_NVME); #define CACHE_LINE_SIZE(64) #endif -extern uma_zone_t nvme_request_zone; +extern uma_zone_t nvme_request_zone; +extern int32_t nvme_retry_count; struct nvme_request { @@ -122,6 +125,7 @@ struct nvme_request { struct uio *uio; nvme_cb_fn_tcb_fn; void*cb_arg; + int32_t retries; STAILQ_ENTRY(nvme_request) stailq; }; @@ -409,6 +413,7 @@ voidnvme_qpair_submit_tracker(struct nv void nvme_qpair_process_completions(struct nvme_qpair *qpair); void nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req); +void nvme_qpair_reset(struct nvme_qpair *qpair); void nvme_admin_qpair_enable(struct nvme_qpair *qpair); void nvme_admin_qpair_disable(struct nvme_qpair *qpair); Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 21:08:32 2013 (r248760) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 21:14:51 2013 (r248761) @@ -105,7 +105,8 @@ nvme_qpair_complete_tracker(struct nvme_ req = tr->req; error = nvme_completion_is_error(cpl); - retry = error && nvme_completion_is_retry(cpl); + retry = error && nvme_completion_is_retry(cpl) && + req->retries < nvme_retry_count; if (error && print_on_error) { nvme_dump_completion(cpl); @@ -122,9 +123,10 @@ nvme_qpair_complete_tracker(struct nvme_ mtx_lock(&qpair->lock); callout_stop(&tr->timer); - if (retry) + if (retry) { + req->retries++; nvme_qpair_submit_tracker(qpair, tr); - else { + } else { if (req->payload_size > 0 || req->uio != NULL) bus_dmamap_unload(qpair->dma_tag, tr->payload_dma_map); @@ -568,6 +570,12 @@ nvme_qpair_enable(struct nvme_qpai
svn commit: r248762 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:16:53 2013 New Revision: 248762 URL: http://svnweb.freebsd.org/changeset/base/248762 Log: Ensure the controller's MDTS is accounted for in max_xfer_size. The controller's IDENTIFY data contains MDTS (Max Data Transfer Size) to allow the controller to specify the maximum I/O data transfer size. nvme(4) already provides a default maximum, but make sure it does not exceed what MDTS reports. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:14:51 2013 (r248761) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:16:53 2013 (r248762) @@ -457,6 +457,14 @@ nvme_ctrlr_identify(struct nvme_controll nvme_chatham_populate_cdata(ctrlr); #endif + /* +* Use MDTS to ensure our default max_xfer_size doesn't exceed what the +* controller supports. +*/ + if (ctrlr->cdata.mdts > 0) + ctrlr->max_xfer_size = min(ctrlr->max_xfer_size, + ctrlr->min_page_size * (1 << (ctrlr->cdata.mdts))); + return (0); } @@ -923,6 +931,8 @@ nvme_ctrlr_construct(struct nvme_control if (cap_hi.bits.dstrd != 0) return (ENXIO); + ctrlr->min_page_size = 1 << (12 + cap_hi.bits.mpsmin); + /* Get ready timeout value from controller, in units of 500ms. */ cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo); ctrlr->ready_timeout_in_ms = cap_lo.bits.to * 500; Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 21:14:51 2013 (r248761) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 21:16:53 2013 (r248762) @@ -265,6 +265,9 @@ struct nvme_controller { /** maximum i/o size in bytes */ uint32_tmax_xfer_size; + /** minimum page size supported by this controller in bytes */ + uint32_tmin_page_size; + /** interrupt coalescing time period (in microseconds) */ uint32_tint_coal_time; ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248763 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:19:26 2013 New Revision: 248763 URL: http://svnweb.freebsd.org/changeset/base/248763 Log: Remove the is_started flag from struct nvme_controller. This flag was originally added to communicate to the sysctl code which oids should be built, but there are easier ways to do this. This needs to be cleaned up prior to adding new controller states - for example, controller failure. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_sysctl.c Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 21:16:53 2013(r248762) +++ head/sys/dev/nvme/nvme.cTue Mar 26 21:19:26 2013(r248763) @@ -283,7 +283,9 @@ nvme_attach(device_t dev) if (status != 0) return (status); - ctrlr->config_hook.ich_func = nvme_ctrlr_start; + nvme_sysctl_initialize_ctrlr(ctrlr); + + ctrlr->config_hook.ich_func = nvme_ctrlr_start_config_hook; ctrlr->config_hook.ich_arg = ctrlr; config_intrhook_establish(&ctrlr->config_hook); Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:16:53 2013 (r248762) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:19:26 2013 (r248763) @@ -733,7 +733,7 @@ nvme_ctrlr_configure_int_coalescing(stru ctrlr->int_coal_threshold, NULL, NULL); } -void +static void nvme_ctrlr_start(void *ctrlr_arg) { struct nvme_controller *ctrlr = ctrlr_arg; @@ -746,40 +746,31 @@ nvme_ctrlr_start(void *ctrlr_arg) nvme_admin_qpair_enable(&ctrlr->adminq); if (nvme_ctrlr_identify(ctrlr) != 0) - goto err; + return; if (nvme_ctrlr_set_num_qpairs(ctrlr) != 0) - goto err; + return; if (nvme_ctrlr_create_qpairs(ctrlr) != 0) - goto err; + return; if (nvme_ctrlr_construct_namespaces(ctrlr) != 0) - goto err; + return; nvme_ctrlr_configure_aer(ctrlr); nvme_ctrlr_configure_int_coalescing(ctrlr); for (i = 0; i < ctrlr->num_io_queues; i++) nvme_io_qpair_enable(&ctrlr->ioq[i]); +} - ctrlr->is_started = TRUE; - -err: - - if (ctrlr->num_start_attempts == 0) { - /* -* Initialize sysctls, even if controller failed to start, to -* assist with debugging admin queue pair. Only run this -* code on the initial start attempt though, and not -* subsequent start attempts due to controller-level resets. -* -*/ - nvme_sysctl_initialize_ctrlr(ctrlr); - config_intrhook_disestablish(&ctrlr->config_hook); - } +void +nvme_ctrlr_start_config_hook(void *arg) +{ + struct nvme_controller *ctrlr = arg; - ctrlr->num_start_attempts++; + nvme_ctrlr_start(ctrlr); + config_intrhook_disestablish(&ctrlr->config_hook); } static void @@ -906,8 +897,6 @@ nvme_ctrlr_construct(struct nvme_control int timeout_period; ctrlr->dev = dev; - ctrlr->is_started = FALSE; - ctrlr->num_start_attempts = 0; status = nvme_ctrlr_allocate_bar(ctrlr); Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 21:16:53 2013 (r248762) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 21:19:26 2013 (r248763) @@ -250,7 +250,6 @@ struct nvme_controller { struct intr_config_hook config_hook; uint32_tns_identified; uint32_tqueues_created; - uint32_tnum_start_attempts; struct task reset_task; struct taskqueue*taskqueue; @@ -287,8 +286,6 @@ struct nvme_controller { struct cdev *cdev; - boolean_t is_started; - uint32_tnum_aers; struct nvme_async_event_request aer[NVME_MAX_ASYNC_EVENTS]; @@ -401,7 +398,7 @@ voidnvme_ctrlr_destruct(struct nvme_con intnvme_ctrlr_hw_reset(struct nvme_controller *ctrlr); void nvme_ctrlr_reset(struct nvme_controller *ctrlr); /* ctrlr defined as void * to allow use with config_intrhook. */ -void nvme_ctrlr_start(void *ctrlr_arg); +void nvme_ctrlr_start_config_hook(void *ctrlr_arg); void nvme_ctrlr_submit_admin_request(struct nvme_controller *ctrlr, struct nvme_request *req); void nvme_ctrlr_submit_io_request(struct
svn commit: r248764 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:42:53 2013 New Revision: 248764 URL: http://svnweb.freebsd.org/changeset/base/248764 Log: Set Pre-boot Software Load Count to 0 at the end of the controller start process. The spec indicates the OS driver should use Set Features (Software Progress Marker) to set the pre-boot software load count to 0 after the OS driver has successfully been initialized. This allows pre-boot software to determine if there have been any issues with the OS loading. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:19:26 2013 (r248763) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:42:53 2013 (r248764) @@ -762,6 +762,16 @@ nvme_ctrlr_start(void *ctrlr_arg) for (i = 0; i < ctrlr->num_io_queues; i++) nvme_io_qpair_enable(&ctrlr->ioq[i]); + + /* +* Clear software progress marker to 0, to indicate to pre-boot +* software that OS driver load was successful. +* +* Chatham does not support this feature. +*/ + if (pci_get_devid(ctrlr->dev) != CHATHAM_PCI_ID) + nvme_ctrlr_cmd_set_feature(ctrlr, + NVME_FEAT_SOFTWARE_PROGRESS_MARKER, 0, NULL, 0, NULL, NULL); } void ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248765 - head/sys/dev/nvd
Author: jimharris Date: Tue Mar 26 21:45:37 2013 New Revision: 248765 URL: http://svnweb.freebsd.org/changeset/base/248765 Log: Have nvd(4) register for controller notifications. Also have nvd maintain controller/namespace relationships internally. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvd/nvd.c Modified: head/sys/dev/nvd/nvd.c == --- head/sys/dev/nvd/nvd.c Tue Mar 26 21:42:53 2013(r248764) +++ head/sys/dev/nvd/nvd.c Tue Mar 26 21:45:37 2013(r248765) @@ -45,9 +45,11 @@ struct nvd_disk; static disk_ioctl_t nvd_ioctl; static disk_strategy_t nvd_strategy; -static void *create_geom_disk(struct nvme_namespace *ns, void *ctrlr); +static void *nvd_new_disk(struct nvme_namespace *ns, void *ctrlr); static void destroy_geom_disk(struct nvd_disk *ndisk); +static void *nvd_new_controller(struct nvme_controller *ctrlr); + static int nvd_load(void); static void nvd_unload(void); @@ -67,10 +69,18 @@ struct nvd_disk { uint32_tcur_depth; - TAILQ_ENTRY(nvd_disk) tailq; + TAILQ_ENTRY(nvd_disk) global_tailq; + TAILQ_ENTRY(nvd_disk) ctrlr_tailq; +}; + +struct nvd_controller { + + TAILQ_ENTRY(nvd_controller) tailq; + TAILQ_HEAD(, nvd_disk) disk_head; }; -TAILQ_HEAD(, nvd_disk) nvd_head; +static TAILQ_HEAD(, nvd_controller)ctrlr_head; +static TAILQ_HEAD(disk_list, nvd_disk) disk_head; static int nvd_modevent(module_t mod, int type, void *arg) { @@ -104,8 +114,11 @@ static int nvd_load() { - TAILQ_INIT(&nvd_head); - consumer_handle = nvme_register_consumer(create_geom_disk, NULL, NULL); + TAILQ_INIT(&ctrlr_head); + TAILQ_INIT(&disk_head); + + consumer_handle = nvme_register_consumer(nvd_new_disk, + nvd_new_controller, NULL); return (consumer_handle != NULL ? 0 : -1); } @@ -113,13 +126,20 @@ nvd_load() static void nvd_unload() { - struct nvd_disk *nvd; + struct nvd_controller *ctrlr; + struct nvd_disk *disk; + + while (!TAILQ_EMPTY(&ctrlr_head)) { + ctrlr = TAILQ_FIRST(&ctrlr_head); + TAILQ_REMOVE(&ctrlr_head, ctrlr, tailq); + free(ctrlr, M_NVD); + } - while (!TAILQ_EMPTY(&nvd_head)) { - nvd = TAILQ_FIRST(&nvd_head); - TAILQ_REMOVE(&nvd_head, nvd, tailq); - destroy_geom_disk(nvd); - free(nvd, M_NVD); + while (!TAILQ_EMPTY(&disk_head)) { + disk = TAILQ_FIRST(&disk_head); + TAILQ_REMOVE(&disk_head, disk, global_tailq); + destroy_geom_disk(disk); + free(disk, M_NVD); } nvme_unregister_consumer(consumer_handle); @@ -234,10 +254,25 @@ nvd_bioq_process(void *arg, int pending) } static void * -create_geom_disk(struct nvme_namespace *ns, void *ctrlr) +nvd_new_controller(struct nvme_controller *ctrlr) { - struct nvd_disk *ndisk; - struct disk *disk; + struct nvd_controller *nvd_ctrlr; + + nvd_ctrlr = malloc(sizeof(struct nvd_controller), M_NVD, + M_ZERO | M_NOWAIT); + + TAILQ_INIT(&nvd_ctrlr->disk_head); + TAILQ_INSERT_TAIL(&ctrlr_head, nvd_ctrlr, tailq); + + return (nvd_ctrlr); +} + +static void * +nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) +{ + struct nvd_disk *ndisk; + struct disk *disk; + struct nvd_controller *ctrlr = ctrlr_arg; ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_NOWAIT); @@ -251,10 +286,11 @@ create_geom_disk(struct nvme_namespace * disk->d_sectorsize = nvme_ns_get_sector_size(ns); disk->d_mediasize = (off_t)nvme_ns_get_size(ns); - if (TAILQ_EMPTY(&nvd_head)) + if (TAILQ_EMPTY(&disk_head)) disk->d_unit = 0; else - disk->d_unit = TAILQ_FIRST(&nvd_head)->disk->d_unit + 1; + disk->d_unit = + TAILQ_LAST(&disk_head, disk_list)->disk->d_unit + 1; disk->d_flags = 0; @@ -286,7 +322,8 @@ create_geom_disk(struct nvme_namespace * taskqueue_thread_enqueue, &ndisk->tq); taskqueue_start_threads(&ndisk->tq, 1, PI_DISK, "nvd taskq"); - TAILQ_INSERT_HEAD(&nvd_head, ndisk, tailq); + TAILQ_INSERT_TAIL(&disk_head, ndisk, global_tailq); + TAILQ_INSERT_TAIL(&ctrlr->disk_head, ndisk, ctrlr_tailq); return (NULL); } ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248766 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 21:48:41 2013 New Revision: 248766 URL: http://svnweb.freebsd.org/changeset/base/248766 Log: Just disable the controller instead of deleting IO queues during detach. This is just as effective, and removes the need for a bunch of admin commands to a controller that's going to be disabled shortly anyways. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:45:37 2013 (r248765) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 21:48:41 2013 (r248766) @@ -1013,6 +1013,7 @@ nvme_ctrlr_destruct(struct nvme_controll { int i; + nvme_ctrlr_disable(ctrlr); taskqueue_free(ctrlr->taskqueue); for (i = 0; i < NVME_MAX_NAMESPACES; i++) Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 21:45:37 2013 (r248765) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 21:48:41 2013 (r248766) @@ -324,6 +324,21 @@ nvme_qpair_destroy(struct nvme_qpair *qp bus_release_resource(qpair->ctrlr->dev, SYS_RES_IRQ, rman_get_rid(qpair->res), qpair->res); + if (qpair->cmd) { + bus_dmamap_unload(qpair->dma_tag, qpair->cmd_dma_map); + bus_dmamap_destroy(qpair->dma_tag, qpair->cmd_dma_map); + contigfree(qpair->cmd, + qpair->num_entries * sizeof(struct nvme_command), M_NVME); + } + + if (qpair->cpl) { + bus_dmamap_unload(qpair->dma_tag, qpair->cpl_dma_map); + bus_dmamap_destroy(qpair->dma_tag, qpair->cpl_dma_map); + contigfree(qpair->cpl, + qpair->num_entries * sizeof(struct nvme_completion), + M_NVME); + } + if (qpair->dma_tag) bus_dma_tag_destroy(qpair->dma_tag); @@ -362,72 +377,14 @@ nvme_admin_qpair_destroy(struct nvme_qpa { nvme_admin_qpair_abort_aers(qpair); - - /* -* For NVMe, you don't send delete queue commands for the admin -* queue, so we just need to unload and free the cmd and cpl memory. -*/ - bus_dmamap_unload(qpair->dma_tag, qpair->cmd_dma_map); - bus_dmamap_destroy(qpair->dma_tag, qpair->cmd_dma_map); - - contigfree(qpair->cmd, - qpair->num_entries * sizeof(struct nvme_command), M_NVME); - - bus_dmamap_unload(qpair->dma_tag, qpair->cpl_dma_map); - bus_dmamap_destroy(qpair->dma_tag, qpair->cpl_dma_map); - contigfree(qpair->cpl, - qpair->num_entries * sizeof(struct nvme_completion), M_NVME); - nvme_qpair_destroy(qpair); } -static void -nvme_free_cmd_ring(void *arg, const struct nvme_completion *status) -{ - struct nvme_qpair *qpair; - - qpair = (struct nvme_qpair *)arg; - bus_dmamap_unload(qpair->dma_tag, qpair->cmd_dma_map); - bus_dmamap_destroy(qpair->dma_tag, qpair->cmd_dma_map); - contigfree(qpair->cmd, - qpair->num_entries * sizeof(struct nvme_command), M_NVME); - qpair->cmd = NULL; -} - -static void -nvme_free_cpl_ring(void *arg, const struct nvme_completion *status) -{ - struct nvme_qpair *qpair; - - qpair = (struct nvme_qpair *)arg; - bus_dmamap_unload(qpair->dma_tag, qpair->cpl_dma_map); - bus_dmamap_destroy(qpair->dma_tag, qpair->cpl_dma_map); - contigfree(qpair->cpl, - qpair->num_entries * sizeof(struct nvme_completion), M_NVME); - qpair->cpl = NULL; -} - void nvme_io_qpair_destroy(struct nvme_qpair *qpair) { - struct nvme_controller *ctrlr = qpair->ctrlr; - - if (qpair->num_entries > 0) { - nvme_ctrlr_cmd_delete_io_sq(ctrlr, qpair, nvme_free_cmd_ring, - qpair); - /* Spin until free_cmd_ring sets qpair->cmd to NULL. */ - while (qpair->cmd) - DELAY(5); - - nvme_ctrlr_cmd_delete_io_cq(ctrlr, qpair, nvme_free_cpl_ring, - qpair); - /* Spin until free_cpl_ring sets qpair->cmd to NULL. */ - while (qpair->cpl) - DELAY(5); - - nvme_qpair_destroy(qpair); - } + nvme_qpair_destroy(qpair); } static void ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248767 - in head/sys/dev: nvd nvme
Author: jimharris Date: Tue Mar 26 21:58:38 2013 New Revision: 248767 URL: http://svnweb.freebsd.org/changeset/base/248767 Log: Add the ability to internally mark a controller as failed, if it is unable to start or reset. Also add a notifier for NVMe consumers for controller fail conditions and plumb this notifier for nvd(4) to destroy the associated GEOM disks when a failure occurs. This requires a bit of work to cover the races when a consumer is sending I/O requests to a controller that is transitioning to the failed state. To help cover this condition, add a task to defer completion of I/Os submitted to a failed controller, so that the consumer will still always receive its completions in a different context than the submission. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvd/nvd.c head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvd/nvd.c == --- head/sys/dev/nvd/nvd.c Tue Mar 26 21:48:41 2013(r248766) +++ head/sys/dev/nvd/nvd.c Tue Mar 26 21:58:38 2013(r248767) @@ -49,6 +49,7 @@ static void *nvd_new_disk(struct nvme_na static void destroy_geom_disk(struct nvd_disk *ndisk); static void *nvd_new_controller(struct nvme_controller *ctrlr); +static void nvd_controller_fail(void *ctrlr); static int nvd_load(void); static void nvd_unload(void); @@ -118,7 +119,7 @@ nvd_load() TAILQ_INIT(&disk_head); consumer_handle = nvme_register_consumer(nvd_new_disk, - nvd_new_controller, NULL); + nvd_new_controller, NULL, nvd_controller_fail); return (consumer_handle != NULL ? 0 : -1); } @@ -351,3 +352,22 @@ destroy_geom_disk(struct nvd_disk *ndisk mtx_destroy(&ndisk->bioqlock); } + +static void +nvd_controller_fail(void *ctrlr_arg) +{ + struct nvd_controller *ctrlr = ctrlr_arg; + struct nvd_disk *disk; + + while (!TAILQ_EMPTY(&ctrlr->disk_head)) { + disk = TAILQ_FIRST(&ctrlr->disk_head); + TAILQ_REMOVE(&disk_head, disk, global_tailq); + TAILQ_REMOVE(&ctrlr->disk_head, disk, ctrlr_tailq); + destroy_geom_disk(disk); + free(disk, M_NVD); + } + + TAILQ_REMOVE(&ctrlr_head, ctrlr, tailq); + free(ctrlr, M_NVD); +} + Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 21:48:41 2013(r248766) +++ head/sys/dev/nvme/nvme.cTue Mar 26 21:58:38 2013(r248767) @@ -44,6 +44,7 @@ struct nvme_consumer { nvme_cons_ns_fn_t ns_fn; nvme_cons_ctrlr_fn_tctrlr_fn; nvme_cons_async_fn_tasync_fn; + nvme_cons_fail_fn_t fail_fn; }; struct nvme_consumer nvme_consumer[NVME_MAX_CONSUMERS]; @@ -349,9 +350,23 @@ nvme_notify_async_consumers(struct nvme_ } } +void +nvme_notify_fail_consumers(struct nvme_controller *ctrlr) +{ + struct nvme_consumer*cons; + uint32_ti; + + for (i = 0; i < NVME_MAX_CONSUMERS; i++) { + cons = &nvme_consumer[i]; + if (cons->id != INVALID_CONSUMER_ID && cons->fail_fn != NULL) + cons->fail_fn(ctrlr->cons_cookie[i]); + } +} + struct nvme_consumer * nvme_register_consumer(nvme_cons_ns_fn_t ns_fn, nvme_cons_ctrlr_fn_t ctrlr_fn, - nvme_cons_async_fn_t async_fn) + nvme_cons_async_fn_t async_fn, + nvme_cons_fail_fn_t fail_fn) { int i; @@ -365,6 +380,7 @@ nvme_register_consumer(nvme_cons_ns_fn_t nvme_consumer[i].ns_fn = ns_fn; nvme_consumer[i].ctrlr_fn = ctrlr_fn; nvme_consumer[i].async_fn = async_fn; + nvme_consumer[i].fail_fn = fail_fn; nvme_notify_consumer(&nvme_consumer[i]); return (&nvme_consumer[i]); Modified: head/sys/dev/nvme/nvme.h == --- head/sys/dev/nvme/nvme.hTue Mar 26 21:48:41 2013(r248766) +++ head/sys/dev/nvme/nvme.hTue Mar 26 21:58:38 2013(r248767) @@ -733,6 +733,7 @@ typedef void *(*nvme_cons_ns_fn_t)(struc typedef void *(*nvme_cons_ctrlr_fn_t)(struct nvme_controller *); typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *, uint32_t, void *, uint32_t); +typedef void (*nvme_cons_fail_fn_t)(void *); enum nvme_namespace_flags { NVME_NS_DEALLOCATE_SUPPORTED= 0x1, @@ -769,7 +770,8 @@ int nvme_ns_cmd_flush(struct nvme_namesp /* Registration functions */ struct nvme_consumer * nvme_register_consumer(n
svn commit: r248768 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 22:06:05 2013 New Revision: 248768 URL: http://svnweb.freebsd.org/changeset/base/248768 Log: Abort and do not retry any outstanding admin commands left over after a controller reset. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 21:58:38 2013 (r248767) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 22:06:05 2013 (r248768) @@ -594,6 +594,21 @@ nvme_qpair_reset(struct nvme_qpair *qpai void nvme_admin_qpair_enable(struct nvme_qpair *qpair) { + struct nvme_tracker *tr; + struct nvme_tracker *tr_temp; + + /* +* Manually abort each outstanding admin command. Do not retry +* admin commands found here, since they will be left over from +* a controller reset and its likely the context in which the +* command was issued no longer applies. +*/ + TAILQ_FOREACH_SAFE(tr, &qpair->outstanding_tr, tailq, tr_temp) { + device_printf(qpair->ctrlr->dev, + "aborting outstanding admin command\n"); + nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC, + NVME_SC_ABORTED_BY_REQUEST, 1 /* do not retry */, TRUE); + } nvme_qpair_enable(qpair); } ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248769 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 22:09:51 2013 New Revision: 248769 URL: http://svnweb.freebsd.org/changeset/base/248769 Log: Replace usages of mtx_pool_find used for admin commands with a polling mechanism. Now that all requests are timed, we are guaranteed to get a completion notification, even if it is an abort status due to a timed out admin command. This has the effect of simplifying the controller and namespace setup code, so that it reads straight through rather than broken up into a bunch of different callback functions. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ns.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme.c == --- head/sys/dev/nvme/nvme.cTue Mar 26 22:06:05 2013(r248768) +++ head/sys/dev/nvme/nvme.cTue Mar 26 22:09:51 2013(r248769) @@ -397,3 +397,18 @@ nvme_unregister_consumer(struct nvme_con consumer->id = INVALID_CONSUMER_ID; } +void +nvme_completion_poll_cb(void *arg, const struct nvme_completion *cpl) +{ + struct nvme_completion_poll_status *status = arg; + + /* +* Copy status into the argument passed by the caller, so that +* the caller can check the status to determine if the +* the request passed or failed. +*/ + memcpy(&status->cpl, cpl, sizeof(*cpl)); + wmb(); + status->done = TRUE; +} + Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 22:06:05 2013 (r248768) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 22:09:51 2013 (r248769) @@ -41,24 +41,6 @@ __FBSDID("$FreeBSD$"); static void nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr, struct nvme_async_event_request *aer); -static void -nvme_ctrlr_cb(void *arg, const struct nvme_completion *status) -{ - struct nvme_completion *cpl = arg; - struct mtx *mtx; - - /* -* Copy status into the argument passed by the caller, so that -* the caller can check the status to determine if the -* the request passed or failed. -*/ - memcpy(cpl, status, sizeof(*cpl)); - mtx = mtx_pool_find(mtxpool_sleep, cpl); - mtx_lock(mtx); - wakeup(cpl); - mtx_unlock(mtx); -} - static int nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr) { @@ -479,18 +461,14 @@ nvme_ctrlr_reset(struct nvme_controller static int nvme_ctrlr_identify(struct nvme_controller *ctrlr) { - struct mtx *mtx; - struct nvme_completion cpl; - int status; - - mtx = mtx_pool_find(mtxpool_sleep, &cpl); + struct nvme_completion_poll_status status; - mtx_lock(mtx); + status.done = FALSE; nvme_ctrlr_cmd_identify_controller(ctrlr, &ctrlr->cdata, - nvme_ctrlr_cb, &cpl); - status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); - mtx_unlock(mtx); - if ((status != 0) || nvme_completion_is_error(&cpl)) { + nvme_completion_poll_cb, &status); + while (status.done == FALSE) + DELAY(5); + if (nvme_completion_is_error(&status.cpl)) { printf("nvme_identify_controller failed!\n"); return (ENXIO); } @@ -514,18 +492,15 @@ nvme_ctrlr_identify(struct nvme_controll static int nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) { - struct mtx *mtx; - struct nvme_completion cpl; - int cq_allocated, sq_allocated, status; - - mtx = mtx_pool_find(mtxpool_sleep, &cpl); + struct nvme_completion_poll_status status; + int cq_allocated, sq_allocated; - mtx_lock(mtx); + status.done = FALSE; nvme_ctrlr_cmd_set_num_queues(ctrlr, ctrlr->num_io_queues, - nvme_ctrlr_cb, &cpl); - status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); - mtx_unlock(mtx); - if ((status != 0) || nvme_completion_is_error(&cpl)) { + nvme_completion_poll_cb, &status); + while (status.done == FALSE) + DELAY(5); + if (nvme_completion_is_error(&status.cpl)) { printf("nvme_set_num_queues failed!\n"); return (ENXIO); } @@ -535,8 +510,8 @@ nvme_ctrlr_set_num_qpairs(struct nvme_co * Lower 16-bits indicate number of submission queues allocated. * Upper 16-bits indicate number of completion queues allocated. */ - sq_allocated = (cpl.cdw0 & 0x) + 1; - cq_allocated = (cpl.cdw0 >> 16) + 1; + sq_allocated = (status.cpl.cdw0 & 0x) + 1; + cq_alloc
svn commit: r248770 - in head/sys/dev: nvd nvme
Author: jimharris Date: Tue Mar 26 22:11:34 2013 New Revision: 248770 URL: http://svnweb.freebsd.org/changeset/base/248770 Log: Change a number of malloc(9) calls to use M_WAITOK instead of M_NOWAIT. Sponsored by: Intel Suggested by: carl Reviewed by: carl Modified: head/sys/dev/nvd/nvd.c head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ns.c head/sys/dev/nvme/nvme_qpair.c head/sys/dev/nvme/nvme_test.c Modified: head/sys/dev/nvd/nvd.c == --- head/sys/dev/nvd/nvd.c Tue Mar 26 22:09:51 2013(r248769) +++ head/sys/dev/nvd/nvd.c Tue Mar 26 22:11:34 2013(r248770) @@ -260,7 +260,7 @@ nvd_new_controller(struct nvme_controlle struct nvd_controller *nvd_ctrlr; nvd_ctrlr = malloc(sizeof(struct nvd_controller), M_NVD, - M_ZERO | M_NOWAIT); + M_ZERO | M_WAITOK); TAILQ_INIT(&nvd_ctrlr->disk_head); TAILQ_INSERT_TAIL(&ctrlr_head, nvd_ctrlr, tailq); @@ -275,7 +275,7 @@ nvd_new_disk(struct nvme_namespace *ns, struct disk *disk; struct nvd_controller *ctrlr = ctrlr_arg; - ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_NOWAIT); + ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_WAITOK); disk = disk_alloc(); disk->d_strategy = nvd_strategy; Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 22:09:51 2013 (r248769) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 22:11:34 2013 (r248770) @@ -263,10 +263,7 @@ nvme_ctrlr_construct_io_qpairs(struct nv ctrlr->max_xfer_size = NVME_MAX_XFER_SIZE; ctrlr->ioq = malloc(ctrlr->num_io_queues * sizeof(struct nvme_qpair), - M_NVME, M_ZERO | M_NOWAIT); - - if (ctrlr->ioq == NULL) - return (ENOMEM); + M_NVME, M_ZERO | M_WAITOK); for (i = 0; i < ctrlr->num_io_queues; i++) { qpair = &ctrlr->ioq[i]; Modified: head/sys/dev/nvme/nvme_ns.c == --- head/sys/dev/nvme/nvme_ns.c Tue Mar 26 22:09:51 2013(r248769) +++ head/sys/dev/nvme/nvme_ns.c Tue Mar 26 22:11:34 2013(r248770) @@ -254,7 +254,7 @@ nvme_ns_bio_process(struct nvme_namespac */ dsm_range = malloc(sizeof(struct nvme_dsm_range), M_NVME, - M_ZERO | M_NOWAIT); + M_ZERO | M_WAITOK); dsm_range->length = bp->bio_bcount/nvme_ns_get_sector_size(ns); dsm_range->starting_lba = Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 22:09:51 2013 (r248769) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 22:11:34 2013 (r248770) @@ -297,12 +297,11 @@ nvme_qpair_construct(struct nvme_qpair * qpair->num_cmds = 0; qpair->num_intr_handler_calls = 0; - /* TODO: error checking on contigmalloc, bus_dmamap_load calls */ qpair->cmd = contigmalloc(qpair->num_entries * - sizeof(struct nvme_command), M_NVME, M_ZERO | M_NOWAIT, + sizeof(struct nvme_command), M_NVME, M_ZERO, 0, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); qpair->cpl = contigmalloc(qpair->num_entries * - sizeof(struct nvme_completion), M_NVME, M_ZERO | M_NOWAIT, + sizeof(struct nvme_completion), M_NVME, M_ZERO, 0, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); bus_dmamap_create(qpair->dma_tag, 0, &qpair->cmd_dma_map); @@ -323,19 +322,13 @@ nvme_qpair_construct(struct nvme_qpair * STAILQ_INIT(&qpair->queued_req); for (i = 0; i < qpair->num_trackers; i++) { - tr = malloc(sizeof(*tr), M_NVME, M_ZERO | M_NOWAIT); - - if (tr == NULL) { - printf("warning: nvme tracker malloc failed\n"); - break; - } - + tr = malloc(sizeof(*tr), M_NVME, M_ZERO | M_WAITOK); nvme_qpair_construct_tracker(qpair, tr, i); TAILQ_INSERT_HEAD(&qpair->free_tr, tr, tailq); } qpair->act_tr = malloc(sizeof(struct nvme_tracker *) * qpair->num_entries, - M_NVME, M_ZERO | M_NOWAIT); + M_NVME, M_ZERO | M_WAITOK); } static void Modified: head/sys/dev/nvme/nvme_test.c == --- head/sys/dev/nvme/nvme_test.c Tue Mar 26 22:09:51 2013 (r248769) +++ head/sys/dev/nvme/nvme_test.c Tue Mar 26 22:11:34 2013 (r248770) @@ -96,7 +96,7 @@ nvme_ns_bio_test(void *arg) int ref; #endif -
svn commit: r248771 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 22:13:07 2013 New Revision: 248771 URL: http://svnweb.freebsd.org/changeset/base/248771 Log: Move common code from the different nvme_allocate_request functions into a separate function. Sponsored by: Intel Suggested by: carl Reviewed by: carl Modified: head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme_private.h == --- head/sys/dev/nvme/nvme_private.hTue Mar 26 22:11:34 2013 (r248770) +++ head/sys/dev/nvme/nvme_private.hTue Mar 26 22:13:07 2013 (r248771) @@ -464,21 +464,30 @@ nvme_single_map(void *arg, bus_dma_segme } static __inline struct nvme_request * -nvme_allocate_request(void *payload, uint32_t payload_size, nvme_cb_fn_t cb_fn, - void *cb_arg) +_nvme_allocate_request(nvme_cb_fn_t cb_fn, void *cb_arg) { struct nvme_request *req; req = uma_zalloc(nvme_request_zone, M_NOWAIT | M_ZERO); - if (req == NULL) - return (NULL); + if (req != NULL) { + req->cb_fn = cb_fn; + req->cb_arg = cb_arg; + req->timeout = TRUE; + } + return (req); +} - req->payload = payload; - req->payload_size = payload_size; - req->cb_fn = cb_fn; - req->cb_arg = cb_arg; - req->timeout = TRUE; +static __inline struct nvme_request * +nvme_allocate_request(void *payload, uint32_t payload_size, nvme_cb_fn_t cb_fn, + void *cb_arg) +{ + struct nvme_request *req; + req = _nvme_allocate_request(cb_fn, cb_arg); + if (req != NULL) { + req->payload = payload; + req->payload_size = payload_size; + } return (req); } @@ -487,15 +496,9 @@ nvme_allocate_request_uio(struct uio *ui { struct nvme_request *req; - req = uma_zalloc(nvme_request_zone, M_NOWAIT | M_ZERO); - if (req == NULL) - return (NULL); - - req->uio = uio; - req->cb_fn = cb_fn; - req->cb_arg = cb_arg; - req->timeout = TRUE; - + req = _nvme_allocate_request(cb_fn, cb_arg); + if (req != NULL) + req->uio = uio; return (req); } ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248772 - head/sbin/nvmecontrol
Author: jimharris Date: Tue Mar 26 22:14:47 2013 New Revision: 248772 URL: http://svnweb.freebsd.org/changeset/base/248772 Log: Use errno and strerror to print more descriptive messages when operations fail in nvmecontrol(8). While here, use consistent checks of return values from stat, open and ioctl. Sponsored by: Intel Suggested by: carl Reviewed by: carl Modified: head/sbin/nvmecontrol/nvmecontrol.c Modified: head/sbin/nvmecontrol/nvmecontrol.c == --- head/sbin/nvmecontrol/nvmecontrol.c Tue Mar 26 22:13:07 2013 (r248771) +++ head/sbin/nvmecontrol/nvmecontrol.c Tue Mar 26 22:14:47 2013 (r248772) @@ -245,13 +245,15 @@ devlist(int argc, char *argv[]) fd = open(path, O_RDWR); if (fd < 0) { - printf("Could not open %s.\n", path); + printf("Could not open %s. errno=%d (%s)\n", path, + errno, strerror(errno)); exit_code = EX_NOPERM; continue; } - if (ioctl(fd, NVME_IDENTIFY_CONTROLLER, &cdata) == -1) { - printf("ioctl to %s failed.\n", path); + if (ioctl(fd, NVME_IDENTIFY_CONTROLLER, &cdata) < 0) { + printf("Identify request to %s failed. errno=%d (%s)\n", + path, errno, strerror(errno)); exit_code = EX_IOERR; continue; } @@ -264,12 +266,15 @@ devlist(int argc, char *argv[]) fd = open(path, O_RDWR); if (fd < 0) { - printf("Could not open %s.\n", path); + printf("Could not open %s. errno=%d (%s)\n", + path, errno, strerror(errno)); exit_code = EX_NOPERM; continue; } - if (ioctl(fd, NVME_IDENTIFY_NAMESPACE, &nsdata) == -1) { - printf("ioctl to %s failed.\n", path); + if (ioctl(fd, NVME_IDENTIFY_NAMESPACE, &nsdata) < 0) { + printf("Identify request to %s failed. " + "errno=%d (%s)\n", path, errno, + strerror(errno)); exit_code = EX_IOERR; continue; } @@ -311,19 +316,22 @@ identify_ctrlr(int argc, char *argv[]) sprintf(path, "/dev/%s", argv[optind]); - if (stat(path, &devstat) != 0) { - printf("Invalid device node '%s'.\n", path); + if (stat(path, &devstat) < 0) { + printf("Invalid device node %s. errno=%d (%s)\n", path, errno, + strerror(errno)); exit(EX_IOERR); } fd = open(path, O_RDWR); if (fd < 0) { - printf("Could not open %s.\n", path); + printf("Could not open %s. errno=%d (%s)\n", path, errno, + strerror(errno)); exit(EX_NOPERM); } - if (ioctl(fd, NVME_IDENTIFY_CONTROLLER, &cdata) == -1) { - printf("ioctl to %s failed.\n", path); + if (ioctl(fd, NVME_IDENTIFY_CONTROLLER, &cdata) < 0) { + printf("Identify request to %s failed. errno=%d (%s)\n", path, + errno, strerror(errno)); exit(EX_IOERR); } @@ -370,19 +378,22 @@ identify_ns(int argc, char *argv[]) sprintf(path, "/dev/%s", argv[optind]); - if (stat(path, &devstat) != 0) { - printf("Invalid device node '%s'.\n", path); + if (stat(path, &devstat) < 0) { + printf("Invalid device node %s. errno=%d (%s)\n", path, errno, + strerror(errno)); exit(EX_IOERR); } fd = open(path, O_RDWR); if (fd < 0) { - printf("Could not open %s.\n", path); + printf("Could not open %s. errno=%d (%s)\n", path, errno, + strerror(errno)); exit(EX_NOPERM); } - if (ioctl(fd, NVME_IDENTIFY_NAMESPACE, &nsdata) == -1) { - printf("ioctl to %s failed.\n", path); + if (ioctl(fd, NVME_IDENTIFY_NAMESPACE, &nsdata) < 0) { + printf("Identify request to %s failed. errno=%d (%s)\n", path, + errno, strerror(errno)); exit(EX_IOERR); } @@ -479,7 +490,7 @@ perftest(int argc, char *argv[]) charpath[64]; u_long ioctl_cmd = NVME_IO_TEST; boolnflag, oflag, sflag, tflag; - int err, perthread = 0; + int
svn commit: r248773 - head/sys/dev/nvme
Author: jimharris Date: Tue Mar 26 22:17:10 2013 New Revision: 248773 URL: http://svnweb.freebsd.org/changeset/base/248773 Log: Clean up debug prints. 1) Consistently use device_printf. 2) Make dump_completion and dump_command into something more human-readable. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ctrlr_cmd.c head/sys/dev/nvme/nvme_ns.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_ctrlr.c == --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 22:14:47 2013 (r248772) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 22:17:10 2013 (r248773) @@ -55,7 +55,7 @@ nvme_ctrlr_allocate_bar(struct nvme_cont &ctrlr->resource_id, 0, ~0, 1, RF_ACTIVE); if(ctrlr->resource == NULL) { - device_printf(ctrlr->dev, "unable to allocate pci resource\n"); + nvme_printf(ctrlr, "unable to allocate pci resource\n"); return (ENOMEM); } @@ -88,7 +88,7 @@ nvme_ctrlr_allocate_chatham_bar(struct n RF_ACTIVE); if(ctrlr->chatham_resource == NULL) { - device_printf(ctrlr->dev, "unable to alloc pci resource\n"); + nvme_printf(ctrlr, "unable to alloc pci resource\n"); return (ENOMEM); } @@ -204,8 +204,8 @@ nvme_ctrlr_construct_admin_qpair(struct */ if (num_entries < NVME_MIN_ADMIN_ENTRIES || num_entries > NVME_MAX_ADMIN_ENTRIES) { - printf("nvme: invalid hw.nvme.admin_entries=%d specified\n", - num_entries); + nvme_printf(ctrlr, "invalid hw.nvme.admin_entries=%d " + "specified\n", num_entries); num_entries = NVME_ADMIN_ENTRIES; } @@ -340,8 +340,7 @@ nvme_ctrlr_wait_for_ready(struct nvme_co csts.raw = nvme_mmio_read_4(ctrlr, csts); if (!cc.bits.en) { - device_printf(ctrlr->dev, "%s called with cc.en = 0\n", - __func__); + nvme_printf(ctrlr, "%s called with cc.en = 0\n", __func__); return (ENXIO); } @@ -350,8 +349,8 @@ nvme_ctrlr_wait_for_ready(struct nvme_co while (!csts.bits.rdy) { DELAY(1000); if (ms_waited++ > ctrlr->ready_timeout_in_ms) { - device_printf(ctrlr->dev, "controller did not become " - "ready within %d ms\n", ctrlr->ready_timeout_in_ms); + nvme_printf(ctrlr, "controller did not become ready " + "within %d ms\n", ctrlr->ready_timeout_in_ms); return (ENXIO); } csts.raw = nvme_mmio_read_4(ctrlr, csts); @@ -466,7 +465,7 @@ nvme_ctrlr_identify(struct nvme_controll while (status.done == FALSE) DELAY(5); if (nvme_completion_is_error(&status.cpl)) { - printf("nvme_identify_controller failed!\n"); + nvme_printf(ctrlr, "nvme_identify_controller failed!\n"); return (ENXIO); } @@ -498,7 +497,7 @@ nvme_ctrlr_set_num_qpairs(struct nvme_co while (status.done == FALSE) DELAY(5); if (nvme_completion_is_error(&status.cpl)) { - printf("nvme_set_num_queues failed!\n"); + nvme_printf(ctrlr, "nvme_set_num_queues failed!\n"); return (ENXIO); } @@ -543,7 +542,7 @@ nvme_ctrlr_create_qpairs(struct nvme_con while (status.done == FALSE) DELAY(5); if (nvme_completion_is_error(&status.cpl)) { - printf("nvme_create_io_cq failed!\n"); + nvme_printf(ctrlr, "nvme_create_io_cq failed!\n"); return (ENXIO); } @@ -553,7 +552,7 @@ nvme_ctrlr_create_qpairs(struct nvme_con while (status.done == FALSE) DELAY(5); if (nvme_completion_is_error(&status.cpl)) { - printf("nvme_create_io_sq failed!\n"); + nvme_printf(ctrlr, "nvme_create_io_sq failed!\n"); return (ENXIO); } } @@ -660,11 +659,12 @@ nvme_ctrlr_async_event_cb(void *arg, con return; } - printf("Asynchronous event occurred.\n"); - /* Associated log page is in bits 23:16 of completion entry dw0. */ aer->log_page_id = (cpl->cdw0 & 0xFF) >> 16; + nvme_printf(aer->ctrlr, "async event occurred (log page id=0x%x)\n", + aer->log_page_id); + if (is_log_page_id_valid(aer->log_page_id)) { aer->log_page_size = nvme_ctrlr_get_log_page_size(aer->ctrlr, aer->log_page_id); @@ -809
svn commit: r248774 - head/lib/libc/sys
Author: jilles Date: Tue Mar 26 22:46:56 2013 New Revision: 248774 URL: http://svnweb.freebsd.org/changeset/base/248774 Log: accept(2): Mention inheritance of O_ASYNC and signal destination. While almost nobody uses O_ASYNC, and rightly so, the inheritance of the related properties across accept() is a portability issue like the inheritance of O_NONBLOCK. Modified: head/lib/libc/sys/accept.2 Modified: head/lib/libc/sys/accept.2 == --- head/lib/libc/sys/accept.2 Tue Mar 26 22:17:10 2013(r248773) +++ head/lib/libc/sys/accept.2 Tue Mar 26 22:46:56 2013(r248774) @@ -28,7 +28,7 @@ .\" @(#)accept.2 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd December 11, 1993 +.Dd March 26, 2013 .Dt ACCEPT 2 .Os .Sh NAME @@ -57,7 +57,13 @@ queue of pending connections, creates a and allocates a new file descriptor for the socket which inherits the state of the .Dv O_NONBLOCK -property from the original socket +and +.Dv O_ASYNC +properties and the destination of +.Dv SIGIO +and +.Dv SIGURG +signals from the original socket .Fa s . .Pp If no pending connections are @@ -129,7 +135,11 @@ to pre-process incoming connections. .Pp Portable programs should not rely on the .Dv O_NONBLOCK -property being inherited. +and +.Dv O_ASYNC +properties and the signal destination being inherited, +but should set them explicitly using +.Xr fcntl 2 . .Sh RETURN VALUES The call returns \-1 on error. If it succeeds, it returns a non-negative ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248775 - head/sys/dev/isci
Author: jimharris Date: Tue Mar 26 23:04:06 2013 New Revision: 248775 URL: http://svnweb.freebsd.org/changeset/base/248775 Log: Report support for unmapped I/O by adding PIM_UNMAPPED flag. Submitted by: jhb, scottl Modified: head/sys/dev/isci/isci_controller.c head/sys/dev/isci/isci_io_request.c Modified: head/sys/dev/isci/isci_controller.c == --- head/sys/dev/isci/isci_controller.c Tue Mar 26 22:46:56 2013 (r248774) +++ head/sys/dev/isci/isci_controller.c Tue Mar 26 23:04:06 2013 (r248775) @@ -673,7 +673,8 @@ void isci_action(struct cam_sim *sim, un cpi->version_num = 1; cpi->hba_inquiry = PI_TAG_ABLE; cpi->target_sprt = 0; - cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN; + cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN | + PIM_UNMAPPED; cpi->hba_eng_cnt = 0; cpi->max_target = SCI_MAX_REMOTE_DEVICES - 1; cpi->max_lun = ISCI_MAX_LUN; Modified: head/sys/dev/isci/isci_io_request.c == --- head/sys/dev/isci/isci_io_request.c Tue Mar 26 22:46:56 2013 (r248774) +++ head/sys/dev/isci/isci_io_request.c Tue Mar 26 23:04:06 2013 (r248775) @@ -747,10 +747,6 @@ isci_io_request_execute_scsi_io(union cc io_request->current_sge_index = 0; io_request->parent.remote_device_handle = device->sci_object; - if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) - panic("Unexpected cam data format! flags = 0x%x\n", - ccb->ccb_h.flags); - error = bus_dmamap_load_ccb(io_request->parent.dma_tag, io_request->parent.dma_map, ccb, isci_io_request_construct, io_request, 0x0); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248776 - head/usr.sbin/newsyslog
Author: markj Date: Tue Mar 26 23:11:30 2013 New Revision: 248776 URL: http://svnweb.freebsd.org/changeset/base/248776 Log: Fix interval-based rotations when the -t flag is used. In this case, find the most-recently archived logfile and use its mtime to determine whether or not to rotate, as in the non-timestamped case. Previously we would just try to use the mtime of .0, which always results in a rotation since it generally doesn't exist in the -t case. PR: bin/166448 Approved by: emaste (co-mentor) Tested by:Marco Steinbach MFC after:2 weeks Modified: head/usr.sbin/newsyslog/newsyslog.c Modified: head/usr.sbin/newsyslog/newsyslog.c == --- head/usr.sbin/newsyslog/newsyslog.c Tue Mar 26 23:04:06 2013 (r248775) +++ head/usr.sbin/newsyslog/newsyslog.c Tue Mar 26 23:11:30 2013 (r248776) @@ -276,7 +276,7 @@ static void parse_args(int argc, char ** static int parse_doption(const char *doption); static void usage(void); static int log_trim(const char *logname, const struct conf_entry *log_ent); -static int age_old_log(char *file); +static int age_old_log(const char *file); static void savelog(char *from, char *to); static void createdir(const struct conf_entry *ent, char *dirpart); static void createlog(const struct conf_entry *ent); @@ -1447,20 +1447,78 @@ oldlog_entry_compare(const void *a, cons } /* + * Check whether the file corresponding to dp is an archive of the logfile + * logfname, based on the timefnamefmt format string. Return true and fill out + * tm if this is the case; otherwise return false. + */ +static int +validate_old_timelog(const struct dirent *dp, const char *logfname, struct tm *tm) +{ + size_t logfname_len; + char *s; + int c; + + logfname_len = strlen(logfname); + + if (dp->d_type != DT_REG) + return (0); + /* Ignore everything but files with our logfile prefix. */ + if (strncmp(dp->d_name, logfname, logfname_len) != 0) + return (0); + /* Ignore the actual non-rotated logfile. */ + if (dp->d_namlen == logfname_len) + return (0); + + /* +* Make sure we created have found a logfile, so the +* postfix is valid, IE format is: '.(.[bgx]z)?'. +*/ + if (dp->d_name[logfname_len] != '.') { + if (verbose) + printf("Ignoring %s which has unexpected " + "extension '%s'\n", dp->d_name, + &dp->d_name[logfname_len]); + return (0); + } + if ((s = strptime(&dp->d_name[logfname_len + 1], + timefnamefmt, tm)) == NULL) { + /* +* We could special case "old" sequentially named logfiles here, +* but we do not as that would require special handling to +* decide which one was the oldest compared to "new" time based +* logfiles. +*/ + if (verbose) + printf("Ignoring %s which does not " + "match time format\n", dp->d_name); + return (0); + } + + for (c = 0; c < COMPRESS_TYPES; c++) + if (strcmp(s, compress_type[c].suffix) == 0) + /* We're done. */ + return (1); + + if (verbose) + printf("Ignoring %s which has unexpected extension '%s'\n", + dp->d_name, s); + + return (0); +} + +/* * Delete the oldest logfiles, when using time based filenames. */ static void delete_oldest_timelog(const struct conf_entry *ent, const char *archive_dir) { char *logfname, *s, *dir, errbuf[80]; - int dir_fd, i, logcnt, max_logcnt, valid; + int dir_fd, i, logcnt, max_logcnt; struct oldlog_entry *oldlogs; - size_t logfname_len; struct dirent *dp; const char *cdir; struct tm tm; DIR *dirp; - int c; oldlogs = malloc(MAX_OLDLOGS * sizeof(struct oldlog_entry)); max_logcnt = MAX_OLDLOGS; @@ -1478,7 +1536,6 @@ delete_oldest_timelog(const struct conf_ err(1, "basename()"); if ((logfname = strdup(s)) == NULL) err(1, "strdup()"); - logfname_len = strlen(logfname); if (strcmp(logfname, "/") == 0) errx(1, "Invalid log filename - became '/'"); @@ -1490,51 +1547,9 @@ delete_oldest_timelog(const struct conf_ err(1, "Cannot open log directory '%s'", dir); dir_fd = dirfd(dirp); while ((dp = readdir(dirp)) != NULL) { - if (dp->d_type != DT_REG) + if (validate_old_timelog(dp, logfname, &tm) == 0) continue; - /* Ignore everything but files with our logfile prefix */ - if (strncmp(dp->d_name, logfname,
svn commit: r248777 - head/usr.sbin/config
Author: jkim Date: Tue Mar 26 23:58:13 2013 New Revision: 248777 URL: http://svnweb.freebsd.org/changeset/base/248777 Log: Loosen restrictions for quoted strings. Now we can use more complex strings and "escaped" quote characters. MFC after:1 month Modified: head/usr.sbin/config/main.c Modified: head/usr.sbin/config/main.c == --- head/usr.sbin/config/main.c Tue Mar 26 23:11:30 2013(r248776) +++ head/usr.sbin/config/main.c Tue Mar 26 23:58:13 2013(r248777) @@ -351,16 +351,24 @@ begin: if (ch == '"' || ch == '\'') { int quote = ch; + escaped_nl = 0; while ((ch = getc(fp)) != EOF) { - if (ch == quote) + if (ch == quote && !escaped_nl) break; - if (ch == '\n') { + if (ch == '\n' && !escaped_nl) { *cp = 0; printf("config: missing quote reading `%s'\n", line); exit(2); } + if (ch == '\\' && !escaped_nl) { + escaped_nl = 1; + continue; + } + if (ch != quote && escaped_nl) + *cp++ = '\\'; *cp++ = ch; + escaped_nl = 0; } } else { *cp++ = ch; ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
Re: svn commit: r248777 - head/usr.sbin/config
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 2013-03-26 19:58:13 -0400, Jung-uk Kim wrote: > Author: jkim Date: Tue Mar 26 23:58:13 2013 New Revision: 248777 > URL: http://svnweb.freebsd.org/changeset/base/248777 > > Log: Loosen restrictions for quoted strings. Now we can use more > complex strings and "escaped" quote characters. ... For example, the following files: ... foo.h optionalfoo \ dependency "foo.o" \ compile-with"${NM} -n --defined-only foo.o |\ ${AWK} '{printf \"#define\t%s\t0x%s\n\",$$3,$$1}' > \ ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "foo.h" ... generates Makefile like this: ... foo.h: foo.o ${NM} -n --defined-only foo.o | \ ${AWK} '{printf "#define\t%s\t0x%s\n",$$3,$$1}' > \ ${.TARGET} ... As you can see, everything is literally copied to the Makefile except for the escaped double quote characters. Jung-uk Kim -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.19 (FreeBSD) iQEcBAEBAgAGBQJRUjjfAAoJECXpabHZMqHO6HUIAMPd3Nvxh2Jm6nGcQcUONEvA vMsplLOrGiCB+q/vfqirXcBKLFj+icFrY09150YeqcQJ0AmD91QEilsn+xMtoTpn vriVuL4UVO3yiNNZtgXVUrA9eA6uHQnZVFKI0muxpdbMbGXIbLwH6z7krdsmmj0b UAh1uai3prjuBQ+gSDU60xdAVqre33XvZ3GxQ1pD8RZW9e9T55ravMJG27LKQEC9 7YzX/CB0x9SBwATx0CZ9FMVwXi3XvFTu0mDDfNsKBHWkeJyuRvzy4UNDKf0cIcVu vTLVnflTEY1wC3isZhGzRcP94/YtAaF8L0cP7UKezZmt+eJ4W75L0FE3gV293QI= =ALJm -END PGP SIGNATURE- ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248778 - head/sys/dev/isci
Author: jimharris Date: Wed Mar 27 00:15:22 2013 New Revision: 248778 URL: http://svnweb.freebsd.org/changeset/base/248778 Log: Panic should the SCI framework ever request a pointer into the ccb's data buffer for a ccb that is unmapped. This case is currently not possible, since the SCI framework only requests these pointers for doing SCSI/ATA translation of non- READ/WRITE commands. The panic is more to protect against the unlikely future scenario where additional commands could be unmapped. Sponsored by: Intel Modified: head/sys/dev/isci/isci_io_request.c Modified: head/sys/dev/isci/isci_io_request.c == --- head/sys/dev/isci/isci_io_request.c Tue Mar 26 23:58:13 2013 (r248777) +++ head/sys/dev/isci/isci_io_request.c Wed Mar 27 00:15:22 2013 (r248778) @@ -506,10 +506,31 @@ uint8_t * scif_cb_io_request_get_virtual_address_from_sgl(void * scif_user_io_request, uint32_t byte_offset) { - struct ISCI_IO_REQUEST *isci_request = - (struct ISCI_IO_REQUEST *)scif_user_io_request; + struct ISCI_IO_REQUEST *isci_request; + union ccb *ccb; + + + isci_request = scif_user_io_request; + ccb = isci_request->ccb; + + /* +* This callback is only invoked for SCSI/ATA translation of +* PIO commands such as INQUIRY and READ_CAPACITY, to allow +* the driver to write the translated data directly into the +* data buffer. It is never invoked for READ/WRITE commands. +* The driver currently assumes only READ/WRITE commands will +* be unmapped. +* +* As a safeguard against future changes to unmapped commands, +* add an explicit panic here should the DATA_MASK != VADDR. +* Otherwise, we would return some garbage pointer back to the +* caller which would result in a panic or more subtle data +* corruption later on. +*/ + if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) + panic("%s: requesting pointer into unmapped ccb", __func__); - return (isci_request->ccb->csio.data_ptr + byte_offset); + return (ccb->csio.data_ptr + byte_offset); } /** ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
Re: svn commit: r248773 - head/sys/dev/nvme
On Tue, 26 Mar 2013, Jim Harris wrote: Author: jimharris Date: Tue Mar 26 22:17:10 2013 New Revision: 248773 URL: http://svnweb.freebsd.org/changeset/base/248773 Log: Clean up debug prints. 1) Consistently use device_printf. 2) Make dump_completion and dump_command into something more human-readable. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ctrlr_cmd.c head/sys/dev/nvme/nvme_ns.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c I am not sure which one it is but I guess it's one of these, which breaks i386 builds: /sys/modules/nvme/../../dev/nvme/nvme_qpair.c:130:18: error: format specifies type 'unsigned long' but the argument has type 'unsigned long long' [-Werror,-Wformat] /sys/modules/nvme/../../dev/nvme/nvme_private.h:358:38: note: expanded from macro 'nvme_printf' == --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 22:14:47 2013 (r248772) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 22:17:10 2013 (r248773) + +static void +nvme_admin_qpair_print_command(struct nvme_qpair *qpair, +struct nvme_command *cmd) +{ + + nvme_printf(qpair->ctrlr, "%s (%02x) sqid:%d cid:%d nsid:%x " + "cdw10:%08x cdw11:%08x\n", + get_admin_opcode_string(cmd->opc), cmd->opc, qpair->id, cmd->cid, + cmd->nsid, cmd->cdw10, cmd->cdw11); +} + +static void +nvme_io_qpair_print_command(struct nvme_qpair *qpair, +struct nvme_command *cmd) +{ + + switch (cmd->opc) { + case NVME_OPC_WRITE: + case NVME_OPC_READ: + case NVME_OPC_WRITE_UNCORRECTABLE: + case NVME_OPC_COMPARE: + nvme_printf(qpair->ctrlr, "%s sqid:%d cid:%d nsid:%d " + "lba:%lu len:%d\n", + get_io_opcode_string(cmd->opc), qpair->id, cmd->cid, + cmd->nsid, ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10, + (cmd->cdw12 & 0x) + 1); + break; + case NVME_OPC_FLUSH: + case NVME_OPC_DATASET_MANAGEMENT: + nvme_printf(qpair->ctrlr, "%s sqid:%d cid:%d nsid:%d\n", + get_io_opcode_string(cmd->opc), qpair->id, cmd->cid, + cmd->nsid); + break; + default: + nvme_printf(qpair->ctrlr, "%s (%02x) sqid:%d cid:%d nsid:%d\n", + get_io_opcode_string(cmd->opc), cmd->opc, qpair->id, + cmd->cid, cmd->nsid); + break; + } +} + -- Bjoern A. Zeeb Charles Haddon Spurgeon: "Friendship is one of the sweetest joys of life. Many might have failed beneath the bitterness of their trial had they not found a friend." ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248779 - head/sys/dev/ath
Author: adrian Date: Wed Mar 27 00:35:45 2013 New Revision: 248779 URL: http://svnweb.freebsd.org/changeset/base/248779 Log: * Stop processing after HAL_EIO; this is what the reference driver does. * If we hit an empty queue condition (which I haven't yet root caused, grr.) .. make sure we release the lock before continuing. Modified: head/sys/dev/ath/if_ath_tx_edma.c Modified: head/sys/dev/ath/if_ath_tx_edma.c == --- head/sys/dev/ath/if_ath_tx_edma.c Wed Mar 27 00:15:22 2013 (r248778) +++ head/sys/dev/ath/if_ath_tx_edma.c Wed Mar 27 00:35:45 2013 (r248779) @@ -633,7 +633,7 @@ ath_edma_tx_processq(struct ath_softc *s if (status == HAL_EIO) { device_printf(sc->sc_dev, "%s: invalid TX status?\n", __func__); - continue; + break; } #ifdef ATH_DEBUG_ALQ @@ -676,6 +676,7 @@ ath_edma_tx_processq(struct ath_softc *s device_printf(sc->sc_dev, "%s: Q%d: empty?\n", __func__, ts.ts_queue_id); + ATH_TXQ_UNLOCK(txq); continue; } ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248780 - head/sys/dev/nvme
Author: jimharris Date: Wed Mar 27 00:37:00 2013 New Revision: 248780 URL: http://svnweb.freebsd.org/changeset/base/248780 Log: Fix printf format issue on i386. Reported by: bz Modified: head/sys/dev/nvme/nvme_qpair.c Modified: head/sys/dev/nvme/nvme_qpair.c == --- head/sys/dev/nvme/nvme_qpair.c Wed Mar 27 00:35:45 2013 (r248779) +++ head/sys/dev/nvme/nvme_qpair.c Wed Mar 27 00:37:00 2013 (r248780) @@ -125,9 +125,10 @@ nvme_io_qpair_print_command(struct nvme_ case NVME_OPC_WRITE_UNCORRECTABLE: case NVME_OPC_COMPARE: nvme_printf(qpair->ctrlr, "%s sqid:%d cid:%d nsid:%d " - "lba:%lu len:%d\n", + "lba:%llu len:%d\n", get_io_opcode_string(cmd->opc), qpair->id, cmd->cid, - cmd->nsid, ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10, + cmd->nsid, + ((unsigned long long)cmd->cdw11 << 32) + cmd->cdw10, (cmd->cdw12 & 0x) + 1); break; case NVME_OPC_FLUSH: ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248781 - head/sys/mips/atheros
Author: adrian Date: Wed Mar 27 03:33:19 2013 New Revision: 248781 URL: http://svnweb.freebsd.org/changeset/base/248781 Log: Add the reference clock for each supported chip. Obtained from:Linux (openwrt) Modified: head/sys/mips/atheros/ar71xx_chip.c head/sys/mips/atheros/ar71xx_cpudef.h head/sys/mips/atheros/ar724x_chip.c head/sys/mips/atheros/ar91xx_chip.c Modified: head/sys/mips/atheros/ar71xx_chip.c == --- head/sys/mips/atheros/ar71xx_chip.c Wed Mar 27 00:37:00 2013 (r248780) +++ head/sys/mips/atheros/ar71xx_chip.c Wed Mar 27 03:33:19 2013 (r248781) @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); uint32_t u_ar71xx_cpu_freq; uint32_t u_ar71xx_ahb_freq; uint32_t u_ar71xx_ddr_freq; +uint32_t u_ar71xx_refclk; static void ar71xx_chip_detect_mem_size(void) @@ -91,6 +92,8 @@ ar71xx_chip_detect_sys_frequency(void) uint32_t freq; uint32_t div; + u_ar71xx_refclk = AR71XX_BASE_FREQ; + pll = ATH_READ_REG(AR71XX_PLL_REG_CPU_CONFIG); div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; Modified: head/sys/mips/atheros/ar71xx_cpudef.h == --- head/sys/mips/atheros/ar71xx_cpudef.h Wed Mar 27 00:37:00 2013 (r248780) +++ head/sys/mips/atheros/ar71xx_cpudef.h Wed Mar 27 03:33:19 2013 (r248781) @@ -117,10 +117,12 @@ static inline void ar71xx_device_ddr_flu } /* XXX shouldn't be here! */ +extern uint32_t u_ar71xx_refclk; extern uint32_t u_ar71xx_cpu_freq; extern uint32_t u_ar71xx_ahb_freq; extern uint32_t u_ar71xx_ddr_freq; +static inline uint64_t ar71xx_refclk(void) { return u_ar71xx_refclk; } static inline uint64_t ar71xx_cpu_freq(void) { return u_ar71xx_cpu_freq; } static inline uint64_t ar71xx_ahb_freq(void) { return u_ar71xx_ahb_freq; } static inline uint64_t ar71xx_ddr_freq(void) { return u_ar71xx_ddr_freq; } Modified: head/sys/mips/atheros/ar724x_chip.c == --- head/sys/mips/atheros/ar724x_chip.c Wed Mar 27 00:37:00 2013 (r248780) +++ head/sys/mips/atheros/ar724x_chip.c Wed Mar 27 03:33:19 2013 (r248781) @@ -73,6 +73,8 @@ ar724x_chip_detect_sys_frequency(void) uint32_t freq; uint32_t div; + u_ar71xx_refclk = AR724X_BASE_FREQ; + pll = ATH_READ_REG(AR724X_PLL_REG_CPU_CONFIG); div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); Modified: head/sys/mips/atheros/ar91xx_chip.c == --- head/sys/mips/atheros/ar91xx_chip.c Wed Mar 27 00:37:00 2013 (r248780) +++ head/sys/mips/atheros/ar91xx_chip.c Wed Mar 27 03:33:19 2013 (r248781) @@ -71,6 +71,8 @@ ar91xx_chip_detect_sys_frequency(void) uint32_t freq; uint32_t div; + u_ar71xx_refclk = AR91XX_BASE_FREQ; + pll = ATH_READ_REG(AR91XX_PLL_REG_CPU_CONFIG); div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r248782 - head/sys/mips/atheros
Author: adrian Date: Wed Mar 27 03:38:58 2013 New Revision: 248782 URL: http://svnweb.freebsd.org/changeset/base/248782 Log: Commit initial (unfinished!) support for the AR933x series of embedded CPUs. The AR933x is a mips24k based SoC with an AR9380 series SoC on board, two gigabit ethernet interfaces and an internal 10/100mbit ethernet switch. There's also the normal interfaces (USB, ethernet, uart, GPIO.) The downside? There's a non-ns8250 UART device. With a very basic UART driver (not in this commit) the SoC is initialised and boots up. I'll commit the UART code soon and then link it into the general setup path. This code is a re-implementation based from the Linux kernel / openwrt AR933x support. TODO: * UART (obviously) * All of the ethernet, USB and wifi SoC glue, including ethernet PLL programming. Added: head/sys/mips/atheros/ar933x_chip.c (contents, props changed) head/sys/mips/atheros/ar933x_chip.h (contents, props changed) head/sys/mips/atheros/ar933x_uart.h (contents, props changed) head/sys/mips/atheros/ar933xreg.h (contents, props changed) Added: head/sys/mips/atheros/ar933x_chip.c == --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/atheros/ar933x_chip.c Wed Mar 27 03:38:58 2013 (r248782) @@ -0,0 +1,268 @@ +/*- + * Copyright (c) 2012 Adrian Chadd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +static void +ar933x_chip_detect_mem_size(void) +{ +} + +static void +ar933x_chip_detect_sys_frequency(void) +{ + uint32_t clock_ctrl; + uint32_t cpu_config; + uint32_t freq; + uint32_t t; + + t = ATH_READ_REG(AR933X_RESET_REG_BOOTSTRAP); + if (t & AR933X_BOOTSTRAP_REF_CLK_40) + u_ar71xx_refclk = (40 * 1000 * 1000); + else + u_ar71xx_refclk = (25 * 1000 * 1000); + + clock_ctrl = ATH_READ_REG(AR933X_PLL_CLOCK_CTRL_REG); + if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { + u_ar71xx_cpu_freq = u_ar71xx_refclk; + u_ar71xx_ahb_freq = u_ar71xx_refclk; + u_ar71xx_ddr_freq = u_ar71xx_refclk; + } else { + cpu_config = ATH_READ_REG(AR933X_PLL_CPU_CONFIG_REG); + + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & + AR933X_PLL_CPU_CONFIG_REFDIV_MASK; + freq = u_ar71xx_refclk / t; + + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & + AR933X_PLL_CPU_CONFIG_NINT_MASK; + freq *= t; + + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & + AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; + if (t == 0) + t = 1; + + freq >>= t; + + t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & +AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; + u_ar71xx_cpu_freq = freq / t; + + t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & + AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; + u_ar71xx_ddr_freq = freq / t; + + t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & +AR933X_PLL_CLOCK_CTRL_AHB_