Compare commits

...

34 Commits

Author SHA1 Message Date
David Marchand
a26adb0d6c env_dpdk/pci: fix check on 20.11 EAL API change
RTE_DEV_ALLOWED is an enum and has no associated define, hence checking
for its presence will always be false.
We could test for RTE_DEV_WHITELISTED define, but this macro added for
deprecation warning will be dropped in the future.
Switch to a check on DPDK version.

Fixes: 10ed0eb755 ("env_dpdk/pci: adapt to 20.11 EAL changes")
Signed-off-by: David Marchand <david.marchand@redhat.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5165 (master)

(cherry picked from commit 2e9cd9d7b0)
Change-Id: I75270977b580065b36c753266cbaa5fb73f99eb1
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5175
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2020-11-24 08:03:42 +00:00
David Marchand
a73286870e env_dpdk/pci: adapt to 20.11 EAL changes
DPDK 20.11 renamed device and bus control enums [1].
This is a simple renaming, no change in semantics.

1: https://git.dpdk.org/dpdk/commit/?id=a65a34a85ebf

Signed-off-by: David Marchand <david.marchand@redhat.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5116 (master)

(cherry picked from commit 10ed0eb755)
Change-Id: Ia40bae750ad74f405eb700b47514fca021ffd052
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5135
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2020-11-18 08:16:05 +00:00
Tomasz Zawadzki
ad82ba685e version: 20.10.1 pre
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I105e102e9dff8719644819254c8a792027473aea
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4937
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
2020-11-02 08:36:16 +00:00
Tomasz Zawadzki
e5d26ecc2a SPDK 20.10
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: Ib56970df336aaccdca04b7b132294b732296903a
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4936
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: John Kariuki <John.K.Kariuki@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
2020-10-30 19:33:45 +00:00
Karol Latecki
658d7df6a7 nvme/hotplug.sh: Copy external DPDK libs into test VM
Need to select proper path for passing libs into the VM
in case we're building with custom DPDK.

Signed-off-by: Karol Latecki <karol.latecki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4975 (master)

(cherry picked from commit 097e6e16b9)
Change-Id: I97d301c70adee31b727c6b6673eadac3cbde9817
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4984
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-30 19:33:35 +00:00
Alexey Marchuk
ba9c5abe86 sock/posix: Disable zcopy send by default
Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4978 (master)

(cherry picked from commit 9b19abae3c)
Change-Id: I4825c681d742946dfcf5bdc209356194766a15cd
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4982
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-30 16:15:30 +00:00
Alexey Marchuk
8a0f9cf3a7 nvme_tcp: Fix icreq/icresp handing with zcopy enabled.
There is a problem with TCP zcopy enabled:
1. TCP initiator sends icreq and start polling a qpair. Polling of qpair
actively calls nvme_tcp_read_pdu function
2. nvme_tcp_read_pdu: qpair is in NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH state,
it reads 8 bytes of common PDU header. It determines the type of the PDU
and finds the size of PDU_PSH header.
3. nvme_tcp_read_pdu: qpair is in NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PSH state.
It should read 120 bytes of icresp PDU. The number of bytes which needs to be
read is pdu->psh_len - pdu->psh_valid_bytes. qpair receives 120 bytes
(the full PDU) and calls nvme_tcp_pdu_psh_handle -> nvme_tcp_icresp_handle.
Here we check that we haven't yet received buffer reclaim notification and
simply return from this function. At the same time we continue to poll the qpair.
4. nvme_tcp_read_pdu: qpair is in NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PSH state
and tries to read data from a socket again. The number of bytes is
pdu->psh_len - pdu->psh_valid_bytes. But now pdu->psh_len == pdu->psh_valid_bytes,
so we call nvme_tcp_read_data with zero length.
readv with zero length is commonly used to check errors on the socket,
but in our case there is no errors and readv returns 0.
5. nvme_tcp_read_data treats zero as error and return NVME_TCP_CONNECTION_FATAL.

Fix is to handle icresp, but leave qpair in INITIALIZING state until
we receive acknowledgement for icreqsend_ack. We also move qpair to
NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_READY recv_state so recv_pdu
will be zerofied and qpair will try to read a common PDU header.
But since it is not initialized yet, it won't receive anything
from the target.

Fixes issue #1633

Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4969 (master)

(cherry picked from commit d296fcd8d9)
Change-Id: I22cedefe530a8ac3b51495988ed6265d8fad15bb
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4976
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
2020-10-30 14:51:12 +00:00
Simon A. F. Lund
2209decef9 examples/nvme_fio_plugin: update ZNS section of README
Signed-off-by: Simon A. F. Lund <simon.lund@samsung.com>
Change-Id: I99c82490811314201b53dde59e586538835e0840
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4950
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
(cherry picked from commit f875da4019)
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4897
2020-10-30 12:52:55 +00:00
Simon A. F. Lund
81e12ff27e examples/nvme_fio_plugin: add plugin-option 'initial_zone_reset'
Added plugin-option 'initial_zone_reset', providing the option to reset
all zones on all namespaces with the Zoned Command Set enabled upon
initialization.
The default is not to reset. The option is exposed even when the ZBD
plumbing is not available. However, it will then inform the user that
ZBD/ZNS is not supported instead of resetting.

The plugin-option provides a short-term solution to an observed issue
with consecutive invocations of fio exhausting maximum-active-resources.
A longer-term solution would be to add a 'max_active_zones' limit in fio
and ensure that fio does not exceed that limit.

Signed-off-by: Simon A. F. Lund <simon.lund@samsung.com>
Change-Id: I65341c028a97657370b315fb298bf97651b9bffd
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4949
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
(cherry picked from commit aae84b1f0e)
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4896
2020-10-30 12:52:55 +00:00
Simon A. F. Lund
3c42afe400 examples/nvme_fio_plugin: move completion-helpers
Preparation patch for the addition of the 'initial_zone_reset' plugin-option.

Signed-off-by: Simon A. F. Lund <simon.lund@samsung.com>
Change-Id: I768fc207b74cfa2a516009e10fc2a4646d06ba72
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4948
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
(cherry picked from commit 528ad3b3cf)
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4895
2020-10-30 12:52:55 +00:00
Michael Haeuptle
034d7cc9d7 nvmf: Fixes double triggering of association timer
Fixes issue #1635.

Under rare circumstances, the CC.en and CC.shn are both set
which then results in setting the association timer twice.
This scenario was observed during hot plug testing when the
initiator tries to reset the subsystem that contains the
removed device.
The end result is that when the ctrlr is destructed, then
one of the timers can still fire and access freed memory.

Signed-off-by: Michael Haeuptle <michael.haeuptle@hpe.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4935 (master)

(cherry picked from commit 4409007906)
Change-Id: Ie5880ab325a28f19361f73712bdeb5b58894ee68
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4957
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Michael Haeuptle <michaelhaeuptle@gmail.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
2020-10-29 15:44:07 +00:00
Michael Haeuptle
807019734e nvme: break completion loop when ctrlr is invalid
This fixes #1423 where the completion loop never
breaks when the NVMe ctrlr is no longer present.
This condition can happen during a hot remove.

Signed-off-by: Michael Haeuptle <michael.haeuptle@hpe.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4831 (master)

(cherry picked from commit 7fc48a5ffc)
Change-Id: Ia238c8aeae720832068de28ce4d34a9d233344fb
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4959
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Michael Haeuptle <michaelhaeuptle@gmail.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
2020-10-29 15:44:01 +00:00
Maciej Szwed
ede2227a7c changelog: Add information regarding scheduler implementation
Signed-off-by: Maciej Szwed <maciej.szwed@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4857 (master)

(cherry picked from commit 67109ff88b)
Change-Id: Id389ffb2c6091add92fb2849fac21a0472c8a404
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4960
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
2020-10-29 15:43:52 +00:00
Jim Harris
d3b788e9ab nvme: continue probing ctrlrs even if one fails
It is possible that a single probe_ctx could be used
to probe multiple newly attached nvme controllers.  If
one of those controllers is removed during this process,
the rest of the controllers do not get probed and can
even get stuck in a zombie state.

It is better to just continue with probing the rest of
the controllers.

Fixes issue #1611.

Signed-off-by: Jim Harris <james.r.harris@intel.com>

Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4945 (master)

(cherry picked from commit ddf86600bb)
Change-Id: I4156ee8b50e8d52cfeee7224f210a58bb773e939
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4958
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
2020-10-29 15:43:38 +00:00
Jim Harris
c64c931c52 env_dpdk: add rte_rcu library dependency
rte_hash depends on rte_rcu starting in upcoming
DPDK 20.11 release.  rte_rcu was only added in
DPDK 19.05 release, so we need to check if it
exists before linking it.

Fixes issue #1661.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4947 (master)

(cherry picked from commit f896aa6f10)
Change-Id: I7e343c6f964b03cc62484b57803a3bad00f80288
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4965
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
2020-10-29 15:43:25 +00:00
Jim Harris
52d31fe78d dpdk: move submodule to build rte_rcu library
Signed-off-by: Jim Harris <james.r.harris@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4953 (master)

(cherry picked from commit f2196fcafb)
Change-Id: Ie38573774612ac7ec7cf23367d3233124acd1a66
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4964
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
2020-10-29 15:43:25 +00:00
Jim Harris
3421560144 test/external_code: use variable to hold DPDK lib list
Signed-off-by: Jim Harris <james.r.harris@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4946 (master)

(cherry picked from commit d792356a5a)
Change-Id: Ie4a489926695cc56125f0e18796071f7730190f1
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4963
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
2020-10-29 15:43:25 +00:00
Simon A. F. Lund
bfd7d22df5 examples/nvme_fio_plugin: fix log-msgs. in report_zones() and reset_wp()
In spdk_fio_report_zones(), log_err did not prefix messages with
"spdk/nvme", making it hard to determine who dumped the error-message.
In spdk_fio_reset_wp() log_err described the wrong function.

This change fixes the above.

Signed-off-by: Simon A. F. Lund <simon.lund@samsung.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4916 (master)

(cherry picked from commit 414500c9eb)
Change-Id: I41df6d451e88942806c8b5a3cf9a0902d98cb186
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4941
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Simon A. F. Lund <simon.lund@samsung.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-29 08:10:17 +00:00
Simon A. F. Lund
9c93d81be3 examples/nvme_fio_plugin: fix reset_wp()
When _reset_wp() received a range to reset, then the loop kept resetting
the first zone in the range.
Also, the processing of command-completion were re-using the same
'completion' state, thus a previous completion would short-circuit
command-completion such that it would never be processed.

This change fixes that.

Also, the reset-loop assumes that the given offset is a valid zone-start
LBA, a check is added to verify that and return -EINVAL if it is not.

Signed-off-by: Simon A. F. Lund <simon.lund@samsung.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4915 (master)

(cherry picked from commit 12a44d4745)
Change-Id: I1a1e4be2e1f67c2d8fecb5fc36a211b2dbb5a921
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4940
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Simon A. F. Lund <simon.lund@samsung.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-29 08:10:17 +00:00
Simon A. F. Lund
3a3cfb3292 examples/nvme_fio_plugin: help the user with max_open_zones constraints
When a device has resource-limitations such as the
maximum-open-resources (mor) and this threshold is exceeded, then IO
will fail upon completion. Such behavior is not the most user-friendly
way to tell the user that they should provide a value for the
fio-parameter 'max_open_zones'.

This change provides an arguably more user-friendly approach by checking
whether the device is limited and in case it is:

* Provide a default value for 'max_open_zones', inform the user, and
continue
* Verify 'max_open_zones' and in case of error inform the user and
return error

Signed-off-by: Simon A. F. Lund <simon.lund@samsung.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4914 (master)

(cherry picked from commit 906c2adb86)
Change-Id: I76cb045d560b9ec5701d97b82a62947af11960b6
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4939
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Simon A. F. Lund <simon.lund@samsung.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-29 08:10:17 +00:00
Niklas Cassel
8c6c009fce examples/nvme/identify: print ZNS data structures if supported
Print the Zoned Namespace Command Set Specific data structures,
if the namespace/controller supports them.

spdk_nvme_zns_ctrlr_get_data() returns NULL for a controller
that does not support the ZNS specific controller data struct.

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4839 (master)

(cherry picked from commit 00d197dba2)
Change-Id: I0acd2695976fc598b61591989f612db35ac821db
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4942
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-29 08:10:03 +00:00
Niklas Cassel
4e9a9c4a22 examples/nvme_fio_plugin: fix zone reporting
All zone management receive helper functions (including
spdk_nvme_zns_report_zones()) are implemented to match the parameters of
the zone management receive function in the ZNS specification.

The documentation for spdk_nvme_zns_report_zones() states:
"param partial_report If true, nr_zones field in the zone report indicates
the number of zone descriptors that were successfully written to the zone
report. If false, nr_zones field in the zone report indicates the number
of zone descriptors that match the report_opts criteria."
This matches the description of the "Partial Report" bit in the ZNS spec.

Since the FIO function parse_zone_info() calls the io_ops->report_zones()
function multiple times, until all zones have been reported, it expects
the return from this function to represent the number of zones that were
successfully reported.

By setting the partial_report bit to false, the controller will return
the total number of zones, and since spdk_fio_report_zones() loops until
idx < report->nr_zones, and writes to zbdz[idx], the current code will
overwrite heap memory, since idx will take on index values that are out
of bounds for the memory allocated by the FIO function parse_zone_info().

Therefore, spdk_fio_report_zones() has to set the partial_report bit to
true when calling the NVMe level function spdk_nvme_zns_report_zones().

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4871 (master)

(cherry picked from commit 1e83b640aa)
Change-Id: I8846711bfed4faadac0315b450158293cefa36f4
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4943
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-29 08:09:53 +00:00
Maciej Wawryk
fc9ae4f30f Modifications for using universal qcow2 image in tests
We want to replace few qcow2 images with one universal.
This commit contains:
 - change password in autotest.sh
 - change image path
 - change image name
 - use snapshot mode in hotplug.sh instead of copying base image

Signed-off-by: Maciej Wawryk <maciejx.wawryk@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4551 (master)

(cherry picked from commit c4c37f1cf1)
Change-Id: I75c457fe75f005b0ab43ca909be7886529ed115b
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4944
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-29 08:09:37 +00:00
Changpeng Liu
ea364da638 env/memory: use stack variable when unmapping the dma region
When enable Werror compile option with new kernel(v5.8), there is
following error reported due to the <linux/vfio.h> data structure
change(added a uint8_t data[] variable in new kernel), we can just
put the 'unmap' at the end of the data structure to fix the issue,
I think it's better to just use a stack variable instead.

CC lib/env_dpdk/memory.o
memory.c:63:36: error: field 'unmap' with variable sized type 'struct vfio_iommu_type1_dma_unmap' not
at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
struct vfio_iommu_type1_dma_unmap unmap;
^
1 error generated.

Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4925 (master)

(cherry picked from commit 2c9b5b5af5)
Change-Id: Icf73a3c48a301e74b92b9ae2e2d8715262b2d056
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4938
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-29 08:09:24 +00:00
yidong0635
0e70cb48ab rocksdb/env_spdk: Fix unused warning.
Fuction takes one parameter to print,
others are unused.

spdk/lib/rocksdb/env_spdk.cc: In function
 ‘void rocksdb::base_bdev_event_cb(spdk_bdev_event_type, spdk_bdev*, void*)’:
/spdk/lib/rocksdb/env_spdk.cc:666:70:
error: unused parameter ‘bdev’ [-Werror=unused-parameter]
666 | base_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
      |                                                    ~~~~~~~~~~~~~~~~~~^~~~
/home/yidong/spdk/lib/rocksdb/env_spdk.cc:667:12:
error: unused parameter ‘event_ctx’ [-Werror=unused-parameter]
  667 |      void *event_ctx)
      |      ~~~~~~^~~~~~~~~
Signed-off-by: yidong0635 <dongx.yi@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4929 (master)

(cherry picked from commit a474889bc6)
Change-Id: Ic1cf45443ab1dcdf38d1b9c6bdea2905e94df19c
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4933
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2020-10-29 08:09:09 +00:00
Liu Xiaodong
494848e3a9 reactor: check calloc failure in gather_metrics
A round of _reactors_scheduler_gather_metrics should be stopped
when there is calloc failure.

Signed-off-by: Liu Xiaodong <xiaodong.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4882 (master)

(cherry picked from commit e2f773aafc)
Change-Id: Ic2220c561abb07a849ea37d3c88af3f6d5d1ffa1
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4923
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Xiaodong Liu <xiaodong.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-28 15:03:17 +00:00
Alexey Marchuk
623d5cc456 nvme: Don't log an error when we can't resubmit all requests
In TCP NVME initiator with zero copy enabled requests might be
completed asynchronously - out of qpair_process_completions
context. At the same time we calculate requests completed
asynchronously so that generic NVME layer can resubmit
queued requests after calling qpair_process_requests (or
poll_group_process_requests).
But there is a time gap between async request complete and
qpair_process_completions and the user can submit new IO
thereby decrease the number of free TCP requests. That means
that there might be less free requests than we excpected when
we try to resubmit queued requests.
The solution is change ERRLOG to DEBUG log since it is not a
fatal case.

Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4859 (master)

(cherry picked from commit e385cafa72)
Change-Id: If045ecd331cc6693e8ef450d8e15432dfa5d8812
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4872
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
2020-10-28 08:09:03 +00:00
Liu Xiaodong
0bcafaea56 lib/rocksdb: remove redundant linked blobfs_bdev
blobfs_bdev lib is already added into BLOCKDEV_MODULES_LIST
so it shouldn't be included by application who already
uses BLOCKDEV_MODULES_LIST or ALL_MODULES_LIST.

Fixes issue: #1654

Signed-off-by: Liu Xiaodong <xiaodong.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4876 (master)

(cherry picked from commit b45788036f)
Change-Id: I46a272e4593e19cf14c3ed8b2965797443c37a0d
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4922
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-28 08:08:49 +00:00
Allen Zhu
b5005497db rpc/nvmf.py: pass zero values to SPDK when allowed
in_capsule_data_size/buf_cache_size/sock_priority/max_namespaces can be 0,
which should be passed in nvmf_create_transport/nvmf_create_subsystem commands.

Signed-off-by: Allen Zhu <allenz@mellanox.com>
Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Signed-off-by: Evgeniy Kochetov <evgeniik@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3815 (master)

(cherry picked from commit 96ab62802c)
Change-Id: Ib557cf9f20f7ec2c0b3c31156cd79dbd670ce7e7
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4921
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Allen Zhu <allenz@mellanox.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-28 08:08:37 +00:00
Alexey Marchuk
839af8867e nvmf/tcp: Align recv_buf_size to MIN_SOC_PIPE_SIZE
If the user decided to disable ICD then we have several side effects:
1. SPDK prints several warnings/errors
2. SPDK doesn't create recv pipe and doesn't set SO_RCVBUF socket option.

I think that we should not rely on ICD only when we create recv pipe or
set SO_RCVBUF since data may be transferred in sgls via R2T/H2C and
we still need recv_pipe and SO_RCVBUF for better performance.
Alternative option is to set recv_buf_size as a maximum between
ICD and io_unit_size

Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4755 (master)

(cherry picked from commit c1fbbfbe56)
Change-Id: Ida71ecc099f9a9355e4617f13315a341872d1cb3
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4920
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-28 08:08:37 +00:00
Alexey Marchuk
bf602f12ca nvmf/tcp: Support ICD for fabric/admin commands
According to the SPEC we should support up to 8192 bytes
of ICD for admin and fabric commands. Transport configuration
parameter in_capsule_data_size is applied to all qpair types -
admin and IO. Also we allocate resources when we get a connection
request, so we don't know qpair type at this moment.
Create a list of buffer in TCP poll group to support ICD up
to 8192 bytes when configuration ICD is less than this value.
The number of elements in this pool is hardcoded, it is planned
to add a new configuration parameter later.

Fixes issue #1569
Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4754 (master)

(cherry picked from commit 85fa43241b)
Change-Id: I8589e3e2ea95d515f5503c6de7c1ee40aaf7b6da
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4886
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
2020-10-28 08:08:37 +00:00
Liu Xiaodong
ad97082bd0 bdev_aio: fix interrupt mode notify error
Signed-off-by: Liu Xiaodong <xiaodong.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4865 (master)

(cherry picked from commit 47962dc7a3)
Change-Id: Ie4492aa33028e8090da96e2b592b20293d694120
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4873
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Xiaodong Liu <xiaodong.liu@intel.com>
Reviewed-by: John Kariuki <John.K.Kariuki@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
2020-10-27 15:44:16 +00:00
Jim Harris
05216cb7bf event: deprecate opts.config_file member
Just always put the config file name in json_config_file,
since we now only support JSON.

If user specifies both -c and --json, it will just take
the latter of the two.  This is similar to if the user
specified --json twice.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: Idc21d73acf0e190eda57a7b0c5d9bcfa14e87030
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4858
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
(cherry picked from commit c31ad66893)
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4894
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Xiaodong Liu <xiaodong.liu@intel.com>
2020-10-27 15:44:03 +00:00
Liu Xiaodong
69b16a000f thread: fix warning caused by intr
Fixes issue: #1650

Signed-off-by: Liu Xiaodong <xiaodong.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4869 (master)

(cherry picked from commit a3c3c0b538)
Change-Id: I8935d439fb7d1d1c896ef297baa53db0d2cd538f
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4874
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Xiaodong Liu <xiaodong.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
2020-10-27 15:43:46 +00:00
39 changed files with 546 additions and 167 deletions

View File

@ -1,6 +1,8 @@
# Changelog # Changelog
## v20.10: (Upcoming Release) ## v20.10.1: (Upcoming Release)
## v20.10: NVMe-oF multipath, NVMe ZNS, iSCSI login redirection
### accel ### accel
@ -38,6 +40,19 @@ Removed `spdk_subsystem_config` callback for submodules as part of legacy config
Removed `spdk_app_get_running_config` function that printed configuration in legacy format, Removed `spdk_app_get_running_config` function that printed configuration in legacy format,
and removed `usr1_handler` from `struct spdk_app_opts` callback that was used to call it. and removed `usr1_handler` from `struct spdk_app_opts` callback that was used to call it.
Added SPDK thread scheduler framework which is used to rebalance load among CPU cores.
The scheduler implementation is pluggable and two schedulers are added first, `static` scheduler
and `gscheduler` scheduler.
`static` scheduler is used by default and does not reschedule threads and keeps the initial
assignments.
CPU frequency governor framework and implementation are also added.
`dpdk_governor` is the first implementation and is based on rte_power library of DPDK.
`gscheduler` scheduler utilizes the CPU frequency governor.
Scheduler and governor frameworks are experimental features.
### fio ### fio
Bdev fio_plugin no longer supports legacy configuration files. Options `spdk_conf` and Bdev fio_plugin no longer supports legacy configuration files. Options `spdk_conf` and

View File

@ -208,7 +208,7 @@ if [ $SPDK_RUN_FUNCTIONAL_TEST -eq 1 ]; then
# enabled, it catches SEGV earlier than our handler which # enabled, it catches SEGV earlier than our handler which
# breaks the hotplug logic. # breaks the hotplug logic.
if [ $SPDK_RUN_ASAN -eq 0 ]; then if [ $SPDK_RUN_ASAN -eq 0 ]; then
run_test "nvme_hotplug" test/nvme/hotplug.sh intel run_test "nvme_hotplug" test/nvme/hotplug.sh root
fi fi
fi fi

2
dpdk

@ -1 +1 @@
Subproject commit c3fae14048afdb5cc43c2d2a5364631ae7669493 Subproject commit 7d8b8e4efe4833631f9a03f18d14e7c642927b8b

View File

@ -116,3 +116,33 @@ To your fio-script, also have a look at script-examples provided with fio:
fio/examples/zbd-seq-read.fio fio/examples/zbd-seq-read.fio
fio/examples/zbd-rand-write.fio fio/examples/zbd-rand-write.fio
## Maximum Open Zones
Zoned Namespaces has a resource constraint on the amount of zones which can be in an opened state at
any point in time. You can control how many zones fio will keep in an open state by using the
``--max_open_zones`` option.
The SPDK/NVMe fio io-engine will set a default value if you do not provide one.
## Maximum Active Zones
Zoned Namespaces has a resource constraint on the number of zones that can be active at any point in
time. Unlike ``max_open_zones``, then fio currently do not manage this constraint, and there is thus
no option to limit it either.
When running with the SPDK/NVMe fio io-engine you can be exposed to error messages, in the form of
completion errors, with the NVMe status code of 0xbd ("Too Many Active Zones"). To work around this,
then you can reset all zones before fio start running its jobs by using the engine option:
--initial_zone_reset=1
## Shared Memory Increase
If your device has a lot of zones, fio can give you errors such as:
smalloc: OOM. Consider using --alloc-size to increase the shared memory available.
This is because fio needs to allocate memory for the zone-report, that is, retrieve the state of
zones on the device including auxiliary accounting information. To solve this, then you can follow
fio's advice and increase ``--alloc-size``.

View File

@ -92,6 +92,7 @@ struct spdk_fio_options {
int apptag_mask; int apptag_mask;
char *digest_enable; char *digest_enable;
int enable_vmd; int enable_vmd;
int initial_zone_reset;
}; };
struct spdk_fio_request { struct spdk_fio_request {
@ -254,6 +255,36 @@ get_fio_qpair(struct spdk_fio_thread *fio_thread, struct fio_file *f)
return NULL; return NULL;
} }
/**
* Callback function to use while processing completions until completion-indicator turns non-zero
*/
static void
pcu_cb(void *ctx, const struct spdk_nvme_cpl *cpl)
{
int *completed = ctx;
*completed = spdk_nvme_cpl_is_error(cpl) ? -1 : 1;
}
/**
* Process Completions Until the given 'completed' indicator turns non-zero or an error occurs
*/
static int32_t
pcu(struct spdk_nvme_qpair *qpair, int *completed)
{
int32_t ret;
while (!*completed) {
ret = spdk_nvme_qpair_process_completions(qpair, 1);
if (ret < 0) {
log_err("spdk/nvme: process_compl(): ret: %d\n", ret);
return ret;
}
}
return 0;
}
#endif #endif
static void static void
@ -558,6 +589,34 @@ static int spdk_fio_setup(struct thread_data *td)
g_td_count++; g_td_count++;
pthread_mutex_unlock(&g_mutex); pthread_mutex_unlock(&g_mutex);
if (fio_options->initial_zone_reset == 1) {
#if FIO_HAS_ZBD
struct spdk_fio_qpair *fio_qpair;
TAILQ_FOREACH(fio_qpair, &fio_thread->fio_qpair, link) {
const struct spdk_nvme_zns_ns_data *zns_data;
int completed = 0, err;
if (!fio_qpair->ns) {
continue;
}
zns_data = spdk_nvme_zns_ns_get_data(fio_qpair->ns);
if (!zns_data) {
continue;
}
err = spdk_nvme_zns_reset_zone(fio_qpair->ns, fio_qpair->qpair, 0x0, true,
pcu_cb, &completed);
if (err || pcu(fio_qpair->qpair, &completed) || completed < 0) {
log_err("spdk/nvme: warn: initial_zone_reset: err: %d, cpl: %d\n",
err, completed);
}
}
#else
log_err("spdk/nvme: ZBD/ZNS is not supported\n");
#endif
}
return rc; return rc;
} }
@ -1019,6 +1078,7 @@ spdk_fio_get_zoned_model(struct thread_data *td, struct fio_file *f, enum zbd_zo
{ {
struct spdk_fio_thread *fio_thread = td->io_ops_data; struct spdk_fio_thread *fio_thread = td->io_ops_data;
struct spdk_fio_qpair *fio_qpair = NULL; struct spdk_fio_qpair *fio_qpair = NULL;
const struct spdk_nvme_zns_ns_data *zns_data = NULL;
*model = ZBD_IGNORE; *model = ZBD_IGNORE;
@ -1045,48 +1105,43 @@ spdk_fio_get_zoned_model(struct thread_data *td, struct fio_file *f, enum zbd_zo
return -ENOSYS; return -ENOSYS;
case SPDK_NVME_CSI_ZNS: case SPDK_NVME_CSI_ZNS:
if (!spdk_nvme_zns_ns_get_data(fio_qpair->ns)) { zns_data = spdk_nvme_zns_ns_get_data(fio_qpair->ns);
if (!zns_data) {
log_err("spdk/nvme: file_name: '%s', ZNS is not enabled\n", f->file_name); log_err("spdk/nvme: file_name: '%s', ZNS is not enabled\n", f->file_name);
return -EINVAL; return -EINVAL;
} }
*model = ZBD_HOST_MANAGED; *model = ZBD_HOST_MANAGED;
/** Unlimited open resources, skip checking 'max_open_zones' */
if (0xFFFFFFFF == zns_data->mor) {
return 0;
}
if (!td->o.max_open_zones) {
td->o.max_open_zones = spdk_min(ZBD_MAX_OPEN_ZONES, zns_data->mor + 1);
log_info("spdk/nvme: parameter 'max_open_zones' was unset; assigned: %d.\n",
td->o.max_open_zones);
} else if (td->o.max_open_zones < 0) {
log_err("spdk/nvme: invalid parameter 'max_open_zones': %d\n",
td->o.max_open_zones);
return -EINVAL;
} else if (td->o.max_open_zones > ZBD_MAX_OPEN_ZONES) {
log_err("spdk/nvme: parameter 'max_open_zones': %d exceeds fio-limit: %d\n",
td->o.max_open_zones, ZBD_MAX_OPEN_ZONES);
return -EINVAL;
} else if ((uint32_t)td->o.max_open_zones > (zns_data->mor + 1)) {
log_err("spdk/nvme: parameter 'max_open_zones': %d exceeds dev-limit: %u\n",
td->o.max_open_zones, zns_data->mor + 1);
return -EINVAL;
}
return 0; return 0;
} }
return -EINVAL; return -EINVAL;
} }
/**
* Callback function to use while processing completions until completion-indicator turns non-zero
*/
static void
pcu_cb(void *ctx, const struct spdk_nvme_cpl *cpl)
{
int *completed = ctx;
*completed = spdk_nvme_cpl_is_error(cpl) ? -1 : 1;
}
/**
* Process Completions Until the given 'completed' indicator turns non-zero or an error occurs
*/
static int32_t
pcu(struct spdk_nvme_qpair *qpair, int *completed)
{
int32_t ret;
while (!*completed) {
ret = spdk_nvme_qpair_process_completions(qpair, 1);
if (ret < 0) {
log_err("spdk/nvme: process_compl(): ret: %d\n", ret);
return ret;
}
}
return 0;
}
static uint64_t static uint64_t
spdk_fio_qpair_mdts_nbytes(struct spdk_fio_qpair *fio_qpair) spdk_fio_qpair_mdts_nbytes(struct spdk_fio_qpair *fio_qpair)
{ {
@ -1139,13 +1194,14 @@ spdk_fio_report_zones(struct thread_data *td, struct fio_file *f, uint64_t offse
} }
err = spdk_nvme_zns_report_zones(fio_qpair->ns, fio_qpair->qpair, report, report_nbytes, err = spdk_nvme_zns_report_zones(fio_qpair->ns, fio_qpair->qpair, report, report_nbytes,
offset / lba_nbytes, SPDK_NVME_ZRA_LIST_ALL, false, pcu_cb, offset / lba_nbytes, SPDK_NVME_ZRA_LIST_ALL, true, pcu_cb,
&completed); &completed);
if (err || pcu(fio_qpair->qpair, &completed) || completed < 0) { if (err || pcu(fio_qpair->qpair, &completed) || completed < 0) {
log_err("spdk/nvme: report_zones(): err: %d, cpl: %d\n", err, completed); log_err("spdk/nvme: report_zones(): err: %d, cpl: %d\n", err, completed);
err = err ? err : -EIO; err = err ? err : -EIO;
goto exit; goto exit;
} }
assert(report->nr_zones <= report_nzones_max);
report_nzones = report->nr_zones; report_nzones = report->nr_zones;
for (uint64_t idx = 0; idx < report->nr_zones; ++idx) { for (uint64_t idx = 0; idx < report->nr_zones; ++idx) {
@ -1162,7 +1218,7 @@ spdk_fio_report_zones(struct thread_data *td, struct fio_file *f, uint64_t offse
break; break;
default: default:
log_err("%s: invalid zone-type: 0x%x\n", f->file_name, zdesc->zt); log_err("spdk/nvme: %s: inv. zone-type: 0x%x\n", f->file_name, zdesc->zt);
err = -EIO; err = -EIO;
goto exit; goto exit;
} }
@ -1191,7 +1247,7 @@ spdk_fio_report_zones(struct thread_data *td, struct fio_file *f, uint64_t offse
break; break;
default: default:
log_err("%s: invalid zone-state: 0x%x\n", f->file_name, zdesc->zs); log_err("spdk/nvme: %s: inv. zone-state: 0x%x\n", f->file_name, zdesc->zs);
err = -EIO; err = -EIO;
goto exit; goto exit;
} }
@ -1210,7 +1266,6 @@ spdk_fio_reset_wp(struct thread_data *td, struct fio_file *f, uint64_t offset, u
struct spdk_fio_qpair *fio_qpair = NULL; struct spdk_fio_qpair *fio_qpair = NULL;
const struct spdk_nvme_zns_ns_data *zns = NULL; const struct spdk_nvme_zns_ns_data *zns = NULL;
uint64_t zsze_nbytes, lba_nbytes; uint64_t zsze_nbytes, lba_nbytes;
int completed = 0;
int err = 0; int err = 0;
fio_qpair = get_fio_qpair(fio_thread, f); fio_qpair = get_fio_qpair(fio_thread, f);
@ -1226,11 +1281,19 @@ spdk_fio_reset_wp(struct thread_data *td, struct fio_file *f, uint64_t offset, u
zsze_nbytes = spdk_nvme_zns_ns_get_zone_size(fio_qpair->ns); zsze_nbytes = spdk_nvme_zns_ns_get_zone_size(fio_qpair->ns);
lba_nbytes = spdk_nvme_ns_get_sector_size(fio_qpair->ns); lba_nbytes = spdk_nvme_ns_get_sector_size(fio_qpair->ns);
/** check the assumption that offset is valid zone-start lba */
if (offset % zsze_nbytes) {
log_err("spdk/nvme: offset: %zu is not a valid zslba\n", offset);
return -EINVAL;
}
for (uint64_t cur = offset; cur < offset + length; cur += zsze_nbytes) { for (uint64_t cur = offset; cur < offset + length; cur += zsze_nbytes) {
err = spdk_nvme_zns_reset_zone(fio_qpair->ns, fio_qpair->qpair, offset / lba_nbytes, int completed = 0;
err = spdk_nvme_zns_reset_zone(fio_qpair->ns, fio_qpair->qpair, cur / lba_nbytes,
false, pcu_cb, &completed); false, pcu_cb, &completed);
if (err || pcu(fio_qpair->qpair, &completed) || completed < 0) { if (err || pcu(fio_qpair->qpair, &completed) || completed < 0) {
log_err("spdk/nvme: report_zones(): err: %d, cpl: %d\n", err, completed); log_err("spdk/nvme: zns_reset_zone(): err: %d, cpl: %d\n", err, completed);
err = err ? err : -EIO; err = err ? err : -EIO;
break; break;
} }
@ -1476,6 +1539,16 @@ static struct fio_option options[] = {
.category = FIO_OPT_C_ENGINE, .category = FIO_OPT_C_ENGINE,
.group = FIO_OPT_G_INVALID, .group = FIO_OPT_G_INVALID,
}, },
{
.name = "initial_zone_reset",
.lname = "Reset Zones on initialization",
.type = FIO_OPT_INT,
.off1 = offsetof(struct spdk_fio_options, initial_zone_reset),
.def = "0",
.help = "Reset Zones on initialization (0=disable, 1=Reset All Zones)",
.category = FIO_OPT_C_ENGINE,
.group = FIO_OPT_G_INVALID,
},
{ {
.name = NULL, .name = NULL,
}, },

View File

@ -775,11 +775,50 @@ print_zns_zone_report(void)
g_zone_report = NULL; g_zone_report = NULL;
} }
static void
print_zns_ns_data(const struct spdk_nvme_zns_ns_data *nsdata_zns)
{
printf("ZNS Specific Namespace Data\n");
printf("===========================\n");
printf("Variable Zone Capacity: %s\n",
nsdata_zns->zoc.variable_zone_capacity ? "Yes" : "No");
printf("Zone Active Excursions: %s\n",
nsdata_zns->zoc.zone_active_excursions ? "Yes" : "No");
printf("Read Across Zone Boundaries: %s\n",
nsdata_zns->ozcs.read_across_zone_boundaries ? "Yes" : "No");
if (nsdata_zns->mar == 0xffffffff) {
printf("Max Active Resources: No Limit\n");
} else {
printf("Max Active Resources: %"PRIu32"\n",
nsdata_zns->mar + 1);
}
if (nsdata_zns->mor == 0xffffffff) {
printf("Max Open Resources: No Limit\n");
} else {
printf("Max Open Resources: %"PRIu32"\n",
nsdata_zns->mor + 1);
}
if (nsdata_zns->rrl == 0) {
printf("Reset Recommended Limit: Not Reported\n");
} else {
printf("Reset Recommended Limit: %"PRIu32"\n",
nsdata_zns->rrl);
}
if (nsdata_zns->frl == 0) {
printf("Finish Recommended Limit: Not Reported\n");
} else {
printf("Finish Recommended Limit: %"PRIu32"\n",
nsdata_zns->frl);
}
printf("\n");
}
static void static void
print_namespace(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns) print_namespace(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns)
{ {
const struct spdk_nvme_ctrlr_data *cdata; const struct spdk_nvme_ctrlr_data *cdata;
const struct spdk_nvme_ns_data *nsdata; const struct spdk_nvme_ns_data *nsdata;
const struct spdk_nvme_zns_ns_data *nsdata_zns;
const struct spdk_uuid *uuid; const struct spdk_uuid *uuid;
uint32_t i; uint32_t i;
uint32_t flags; uint32_t flags;
@ -788,6 +827,7 @@ print_namespace(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns)
cdata = spdk_nvme_ctrlr_get_data(ctrlr); cdata = spdk_nvme_ctrlr_get_data(ctrlr);
nsdata = spdk_nvme_ns_get_data(ns); nsdata = spdk_nvme_ns_get_data(ns);
nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
flags = spdk_nvme_ns_get_flags(ns); flags = spdk_nvme_ns_get_flags(ns);
printf("Namespace ID:%d\n", spdk_nvme_ns_get_id(ns)); printf("Namespace ID:%d\n", spdk_nvme_ns_get_id(ns));
@ -888,9 +928,15 @@ print_namespace(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns)
printf("Number of LBA Formats: %d\n", nsdata->nlbaf + 1); printf("Number of LBA Formats: %d\n", nsdata->nlbaf + 1);
printf("Current LBA Format: LBA Format #%02d\n", printf("Current LBA Format: LBA Format #%02d\n",
nsdata->flbas.format); nsdata->flbas.format);
for (i = 0; i <= nsdata->nlbaf; i++) for (i = 0; i <= nsdata->nlbaf; i++) {
printf("LBA Format #%02d: Data Size: %5d Metadata Size: %5d\n", printf("LBA Format #%02d: Data Size: %5d Metadata Size: %5d\n",
i, 1 << nsdata->lbaf[i].lbads, nsdata->lbaf[i].ms); i, 1 << nsdata->lbaf[i].lbads, nsdata->lbaf[i].ms);
if (spdk_nvme_ns_get_csi(ns) == SPDK_NVME_CSI_ZNS) {
printf("LBA Format Extension #%02d: Zone Size (in LBAs): 0x%"PRIx64" Zone Descriptor Extension Size: %d bytes\n",
i, nsdata_zns->lbafe[i].zsze, nsdata_zns->lbafe[i].zdes << 6);
}
}
printf("\n"); printf("\n");
if (spdk_nvme_ctrlr_is_ocssd_supported(ctrlr)) { if (spdk_nvme_ctrlr_is_ocssd_supported(ctrlr)) {
@ -904,6 +950,7 @@ print_namespace(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns)
printf("ERROR: spdk_nvme_ctrlr_alloc_io_qpair() failed\n"); printf("ERROR: spdk_nvme_ctrlr_alloc_io_qpair() failed\n");
exit(1); exit(1);
} }
print_zns_ns_data(nsdata_zns);
get_zns_zone_report(ns, qpair); get_zns_zone_report(ns, qpair);
print_zns_zone_report(); print_zns_zone_report();
spdk_nvme_ctrlr_free_io_qpair(qpair); spdk_nvme_ctrlr_free_io_qpair(qpair);
@ -1754,6 +1801,15 @@ print_controller(struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_transport
printf("\n"); printf("\n");
} }
if (spdk_nvme_zns_ctrlr_get_data(ctrlr)) {
printf("ZNS Specific Controller Data\n");
printf("============================\n");
printf("Zone Append Size Limit: %u\n",
spdk_nvme_zns_ctrlr_get_data(ctrlr)->zasl);
printf("\n");
printf("\n");
}
printf("Active Namespaces\n"); printf("Active Namespaces\n");
printf("=================\n"); printf("=================\n");
for (nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); for (nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr);

View File

@ -1412,8 +1412,8 @@ static void usage(char *program_name)
printf("\t"); printf("\t");
spdk_log_usage(stdout, "-T"); spdk_log_usage(stdout, "-T");
printf("\t[-V enable VMD enumeration]\n"); printf("\t[-V enable VMD enumeration]\n");
printf("\t[-z disable zero copy send for the given sock implementation]\n"); printf("\t[-z disable zero copy send for the given sock implementation. Default for posix impl]\n");
printf("\t[-Z enable zero copy send for the given sock implementation. Default for posix impl]\n"); printf("\t[-Z enable zero copy send for the given sock implementation]\n");
printf("\t[-A IO buffer alignment. Must be power of 2 and not less than cache line (%u)]\n", printf("\t[-A IO buffer alignment. Must be power of 2 and not less than cache line (%u)]\n",
SPDK_CACHE_LINE_SIZE); SPDK_CACHE_LINE_SIZE);
printf("\t[-S set the default sock impl, e.g. \"posix\"]\n"); printf("\t[-S set the default sock impl, e.g. \"posix\"]\n");

View File

@ -89,7 +89,7 @@ typedef void (*spdk_sighandler_t)(int signal);
*/ */
struct spdk_app_opts { struct spdk_app_opts {
const char *name; const char *name;
const char *config_file; const char *config_file; /* deprecated */
const char *json_config_file; const char *json_config_file;
bool json_config_ignore_errors; bool json_config_ignore_errors;
const char *rpc_addr; /* Can be UNIX domain socket path or IP address + TCP port */ const char *rpc_addr; /* Can be UNIX domain socket path or IP address + TCP port */

View File

@ -773,9 +773,16 @@ struct spdk_nvme_probe_ctx *spdk_nvme_probe_async(const struct spdk_nvme_transpo
spdk_nvme_remove_cb remove_cb); spdk_nvme_remove_cb remove_cb);
/** /**
* Start controllers in the context list. * Proceed with attaching contollers associated with the probe context.
* *
* Users may call the function util it returns True. * The probe context is one returned from a previous call to
* spdk_nvme_probe_async(). Users must call this function on the
* probe context until it returns 0.
*
* If any controllers fail to attach, there is no explicit notification.
* Users can detect attachment failure by comparing attach_cb invocations
* with the number of times where the user returned true for the
* probe_cb.
* *
* \param probe_ctx Context used to track probe actions. * \param probe_ctx Context used to track probe actions.
* *
@ -783,7 +790,6 @@ struct spdk_nvme_probe_ctx *spdk_nvme_probe_async(const struct spdk_nvme_transpo
* is also freed and no longer valid. * is also freed and no longer valid.
* \return -EAGAIN if there are still pending probe operations; user must call * \return -EAGAIN if there are still pending probe operations; user must call
* spdk_nvme_probe_poll_async again to continue progress. * spdk_nvme_probe_poll_async again to continue progress.
* \return value other than 0 and -EAGAIN probe error with one controller.
*/ */
int spdk_nvme_probe_poll_async(struct spdk_nvme_probe_ctx *probe_ctx); int spdk_nvme_probe_poll_async(struct spdk_nvme_probe_ctx *probe_ctx);

View File

@ -54,7 +54,7 @@
* Patch level is incremented on maintenance branch releases and reset to 0 for each * Patch level is incremented on maintenance branch releases and reset to 0 for each
* new major.minor release. * new major.minor release.
*/ */
#define SPDK_VERSION_PATCH 0 #define SPDK_VERSION_PATCH 1
/** /**
* Version string suffix. * Version string suffix.

View File

@ -43,7 +43,7 @@
#define SPDK_NVME_TCP_DIGEST_ALIGNMENT 4 #define SPDK_NVME_TCP_DIGEST_ALIGNMENT 4
#define SPDK_NVME_TCP_QPAIR_EXIT_TIMEOUT 30 #define SPDK_NVME_TCP_QPAIR_EXIT_TIMEOUT 30
#define SPDK_NVMF_TCP_RECV_BUF_SIZE_FACTOR 8 #define SPDK_NVMF_TCP_RECV_BUF_SIZE_FACTOR 8
#define SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE 8192u
/* /*
* Maximum number of SGL elements. * Maximum number of SGL elements.
*/ */

View File

@ -114,6 +114,9 @@ endif
ifeq ($(LINK_HASH),y) ifeq ($(LINK_HASH),y)
DPDK_LIB_LIST += rte_hash DPDK_LIB_LIST += rte_hash
ifneq (, $(wildcard $(DPDK_ABS_DIR)/lib/librte_rcu.*))
DPDK_LIB_LIST += rte_rcu
endif
endif endif
DPDK_SHARED_LIB = $(DPDK_LIB_LIST:%=$(DPDK_ABS_DIR)/lib/lib%.so) DPDK_SHARED_LIB = $(DPDK_LIB_LIST:%=$(DPDK_ABS_DIR)/lib/lib%.so)

View File

@ -60,7 +60,6 @@
struct spdk_vfio_dma_map { struct spdk_vfio_dma_map {
struct vfio_iommu_type1_dma_map map; struct vfio_iommu_type1_dma_map map;
struct vfio_iommu_type1_dma_unmap unmap;
TAILQ_ENTRY(spdk_vfio_dma_map) tailq; TAILQ_ENTRY(spdk_vfio_dma_map) tailq;
}; };
@ -820,11 +819,6 @@ vtophys_iommu_map_dma(uint64_t vaddr, uint64_t iova, uint64_t size)
dma_map->map.iova = iova; dma_map->map.iova = iova;
dma_map->map.size = size; dma_map->map.size = size;
dma_map->unmap.argsz = sizeof(dma_map->unmap);
dma_map->unmap.flags = 0;
dma_map->unmap.iova = iova;
dma_map->unmap.size = size;
pthread_mutex_lock(&g_vfio.mutex); pthread_mutex_lock(&g_vfio.mutex);
if (g_vfio.device_ref == 0) { if (g_vfio.device_ref == 0) {
/* VFIO requires at least one device (IOMMU group) to be added to /* VFIO requires at least one device (IOMMU group) to be added to
@ -865,6 +859,7 @@ vtophys_iommu_unmap_dma(uint64_t iova, uint64_t size)
struct spdk_vfio_dma_map *dma_map; struct spdk_vfio_dma_map *dma_map;
uint64_t refcount; uint64_t refcount;
int ret; int ret;
struct vfio_iommu_type1_dma_unmap unmap = {};
pthread_mutex_lock(&g_vfio.mutex); pthread_mutex_lock(&g_vfio.mutex);
TAILQ_FOREACH(dma_map, &g_vfio.maps, tailq) { TAILQ_FOREACH(dma_map, &g_vfio.maps, tailq) {
@ -899,8 +894,11 @@ vtophys_iommu_unmap_dma(uint64_t iova, uint64_t size)
goto out_remove; goto out_remove;
} }
unmap.argsz = sizeof(unmap);
ret = ioctl(g_vfio.fd, VFIO_IOMMU_UNMAP_DMA, &dma_map->unmap); unmap.flags = 0;
unmap.iova = dma_map->map.iova;
unmap.size = dma_map->map.size;
ret = ioctl(g_vfio.fd, VFIO_IOMMU_UNMAP_DMA, &unmap);
if (ret) { if (ret) {
DEBUG_PRINT("Cannot clear DMA mapping, error %d\n", errno); DEBUG_PRINT("Cannot clear DMA mapping, error %d\n", errno);
pthread_mutex_unlock(&g_vfio.mutex); pthread_mutex_unlock(&g_vfio.mutex);
@ -1383,7 +1381,12 @@ vtophys_pci_device_removed(struct rte_pci_device *pci_device)
* of other, external factors. * of other, external factors.
*/ */
TAILQ_FOREACH(dma_map, &g_vfio.maps, tailq) { TAILQ_FOREACH(dma_map, &g_vfio.maps, tailq) {
ret = ioctl(g_vfio.fd, VFIO_IOMMU_UNMAP_DMA, &dma_map->unmap); struct vfio_iommu_type1_dma_unmap unmap = {};
unmap.argsz = sizeof(unmap);
unmap.flags = 0;
unmap.iova = dma_map->map.iova;
unmap.size = dma_map->map.size;
ret = ioctl(g_vfio.fd, VFIO_IOMMU_UNMAP_DMA, &unmap);
if (ret) { if (ret) {
DEBUG_PRINT("Cannot unmap DMA memory, error %d\n", errno); DEBUG_PRINT("Cannot unmap DMA memory, error %d\n", errno);
break; break;

View File

@ -40,6 +40,13 @@
#define SYSFS_PCI_DRIVERS "/sys/bus/pci/drivers" #define SYSFS_PCI_DRIVERS "/sys/bus/pci/drivers"
/* Compatibility for versions < 20.11 */
#if RTE_VERSION < RTE_VERSION_NUM(20, 11, 0, 0)
#define RTE_DEV_ALLOWED RTE_DEV_WHITELISTED
#define RTE_DEV_BLOCKED RTE_DEV_BLACKLISTED
#define RTE_BUS_SCAN_ALLOWLIST RTE_BUS_SCAN_WHITELIST
#endif
#define PCI_CFG_SIZE 256 #define PCI_CFG_SIZE 256
#define PCI_EXT_CAP_ID_SN 0x03 #define PCI_EXT_CAP_ID_SN 0x03
@ -340,7 +347,7 @@ _pci_env_init(void)
{ {
/* We assume devices were present on the bus for more than 2 seconds /* We assume devices were present on the bus for more than 2 seconds
* before initializing SPDK and there's no need to wait more. We scan * before initializing SPDK and there's no need to wait more. We scan
* the bus, but we don't blacklist any devices. * the bus, but we don't block any devices.
*/ */
scan_pci_bus(false); scan_pci_bus(false);
@ -459,7 +466,7 @@ pci_device_fini(struct rte_pci_device *_dev)
return -1; return -1;
} }
/* remove our whitelist_at option */ /* remove our allowed_at option */
if (_dev->device.devargs) { if (_dev->device.devargs) {
_dev->device.devargs->data = NULL; _dev->device.devargs->data = NULL;
} }
@ -518,7 +525,7 @@ scan_pci_bus(bool delay_init)
if (!da) { if (!da) {
char devargs_str[128]; char devargs_str[128];
/* the device was never blacklisted or whitelisted */ /* the device was never blocked or allowed */
da = calloc(1, sizeof(*da)); da = calloc(1, sizeof(*da));
if (!da) { if (!da) {
return -1; return -1;
@ -535,21 +542,21 @@ scan_pci_bus(bool delay_init)
} }
if (da->data) { if (da->data) {
uint64_t whitelist_at = (uint64_t)(uintptr_t)da->data; uint64_t allowed_at = (uint64_t)(uintptr_t)da->data;
/* this device was seen by spdk before... */ /* this device was seen by spdk before... */
if (da->policy == RTE_DEV_BLACKLISTED && whitelist_at <= now) { if (da->policy == RTE_DEV_BLOCKED && allowed_at <= now) {
da->policy = RTE_DEV_WHITELISTED; da->policy = RTE_DEV_ALLOWED;
} }
} else if ((driver->driver.bus->bus.conf.scan_mode == RTE_BUS_SCAN_WHITELIST && } else if ((driver->driver.bus->bus.conf.scan_mode == RTE_BUS_SCAN_ALLOWLIST &&
da->policy == RTE_DEV_WHITELISTED) || da->policy != RTE_DEV_BLACKLISTED) { da->policy == RTE_DEV_ALLOWED) || da->policy != RTE_DEV_BLOCKED) {
/* override the policy only if not permanently blacklisted */ /* override the policy only if not permanently blocked */
if (delay_init) { if (delay_init) {
da->policy = RTE_DEV_BLACKLISTED; da->policy = RTE_DEV_BLOCKED;
da->data = (void *)(now + 2 * spdk_get_ticks_hz()); da->data = (void *)(now + 2 * spdk_get_ticks_hz());
} else { } else {
da->policy = RTE_DEV_WHITELISTED; da->policy = RTE_DEV_ALLOWED;
da->data = (void *)(uintptr_t)now; da->data = (void *)(uintptr_t)now;
} }
} }
@ -619,7 +626,7 @@ spdk_pci_device_attach(struct spdk_pci_driver *driver,
return -1; return -1;
} }
/* explicit attach ignores the whitelist, so if we blacklisted this /* explicit attach ignores the allowlist, so if we blocked this
* device before let's enable it now - just for clarity. * device before let's enable it now - just for clarity.
*/ */
TAILQ_FOREACH(dev, &g_pci_devices, internal.tailq) { TAILQ_FOREACH(dev, &g_pci_devices, internal.tailq) {
@ -633,7 +640,7 @@ spdk_pci_device_attach(struct spdk_pci_driver *driver,
da = rte_dev->device.devargs; da = rte_dev->device.devargs;
if (da && da->data) { if (da && da->data) {
da->data = (void *)(uintptr_t)spdk_get_ticks(); da->data = (void *)(uintptr_t)spdk_get_ticks();
da->policy = RTE_DEV_WHITELISTED; da->policy = RTE_DEV_ALLOWED;
} }
return 0; return 0;

View File

@ -401,6 +401,18 @@ spdk_app_start(struct spdk_app_opts *opts, spdk_msg_fn start_fn,
return 1; return 1;
} }
if (opts->config_file) {
SPDK_ERRLOG("opts->config_file is deprecated. Use opts->json_config_file instead.\n");
/* For now we will just treat config_file as json_config_file. But if both were
* specified we will return an error here.
*/
if (opts->json_config_file) {
SPDK_ERRLOG("Setting both opts->config_file and opts->json_config_file not allowed.\n");
return 1;
}
opts->json_config_file = opts->config_file;
}
if (!start_fn) { if (!start_fn) {
SPDK_ERRLOG("start_fn should not be NULL\n"); SPDK_ERRLOG("start_fn should not be NULL\n");
return 1; return 1;
@ -640,8 +652,6 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts,
while ((ch = getopt_long(argc, argv, cmdline_short_opts, cmdline_options, &opt_idx)) != -1) { while ((ch = getopt_long(argc, argv, cmdline_short_opts, cmdline_options, &opt_idx)) != -1) {
switch (ch) { switch (ch) {
case CONFIG_FILE_OPT_IDX: case CONFIG_FILE_OPT_IDX:
opts->config_file = optarg;
break;
case JSON_CONFIG_OPT_IDX: case JSON_CONFIG_OPT_IDX:
opts->json_config_file = optarg; opts->json_config_file = optarg;
break; break;
@ -823,16 +833,6 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts,
} }
} }
if (opts->config_file) {
if (opts->json_config_file) {
SPDK_ERRLOG("ERROR: --config and --json options can't be used together.\n");
goto out;
}
opts->json_config_file = opts->config_file;
opts->config_file = NULL;
}
if (opts->json_config_file && opts->delay_subsystem_init) { if (opts->json_config_file && opts->delay_subsystem_init) {
SPDK_ERRLOG("JSON configuration file can't be used together with --wait-for-rpc.\n"); SPDK_ERRLOG("JSON configuration file can't be used together with --wait-for-rpc.\n");
goto out; goto out;

View File

@ -517,6 +517,18 @@ _reactors_scheduler_fini(void *arg1, void *arg2)
} }
} }
static void
_reactors_scheduler_cancel(void *arg1, void *arg2)
{
struct spdk_reactor *reactor;
uint32_t i;
SPDK_ENV_FOREACH_CORE(i) {
reactor = spdk_reactor_get(i);
reactor->flags.is_scheduling = false;
}
}
/* Phase 1 of thread scheduling is to gather metrics on the existing threads */ /* Phase 1 of thread scheduling is to gather metrics on the existing threads */
static void static void
_reactors_scheduler_gather_metrics(void *arg1, void *arg2) _reactors_scheduler_gather_metrics(void *arg1, void *arg2)
@ -551,6 +563,14 @@ _reactors_scheduler_gather_metrics(void *arg1, void *arg2)
if (core_info->threads_count > 0) { if (core_info->threads_count > 0) {
core_info->threads = calloc(core_info->threads_count, sizeof(struct spdk_lw_thread *)); core_info->threads = calloc(core_info->threads_count, sizeof(struct spdk_lw_thread *));
if (core_info->threads == NULL) {
SPDK_ERRLOG("Failed to allocate memory when gathering metrics on %u\n", reactor->lcore);
/* Cancel this round of schedule work */
evt = spdk_event_allocate(g_scheduling_reactor->lcore, _reactors_scheduler_cancel, NULL, NULL);
spdk_event_call(evt);
return;
}
i = 0; i = 0;
TAILQ_FOREACH(lw_thread, &reactor->threads, link) { TAILQ_FOREACH(lw_thread, &reactor->threads, link) {

View File

@ -314,6 +314,14 @@ nvme_wait_for_completion_robust_lock_timeout(
rc = -1; rc = -1;
break; break;
} }
if (qpair->ctrlr->trid.trtype == SPDK_NVME_TRANSPORT_PCIE) {
union spdk_nvme_csts_register csts = spdk_nvme_ctrlr_get_regs_csts(qpair->ctrlr);
if (csts.raw == SPDK_NVME_INVALID_REGISTER_VALUE) {
status->cpl.status.sct = SPDK_NVME_SCT_GENERIC;
status->cpl.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
break;
}
}
} }
if (status->done == false) { if (status->done == false) {
@ -688,11 +696,11 @@ nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid,
return 1; return 1;
} }
static int static void
nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr, nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr,
struct spdk_nvme_probe_ctx *probe_ctx) struct spdk_nvme_probe_ctx *probe_ctx)
{ {
int rc = 0; int rc = 0;
rc = nvme_ctrlr_process_init(ctrlr); rc = nvme_ctrlr_process_init(ctrlr);
@ -704,11 +712,11 @@ nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr,
nvme_ctrlr_fail(ctrlr, false); nvme_ctrlr_fail(ctrlr, false);
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock); nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
nvme_ctrlr_destruct(ctrlr); nvme_ctrlr_destruct(ctrlr);
return rc; return;
} }
if (ctrlr->state != NVME_CTRLR_STATE_READY) { if (ctrlr->state != NVME_CTRLR_STATE_READY) {
return 0; return;
} }
STAILQ_INIT(&ctrlr->io_producers); STAILQ_INIT(&ctrlr->io_producers);
@ -735,10 +743,7 @@ nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr,
if (probe_ctx->attach_cb) { if (probe_ctx->attach_cb) {
probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts); probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts);
return 0;
} }
return 0;
} }
static int static int
@ -1545,7 +1550,6 @@ spdk_nvme_probe_async(const struct spdk_nvme_transport_id *trid,
int int
spdk_nvme_probe_poll_async(struct spdk_nvme_probe_ctx *probe_ctx) spdk_nvme_probe_poll_async(struct spdk_nvme_probe_ctx *probe_ctx)
{ {
int rc = 0;
struct spdk_nvme_ctrlr *ctrlr, *ctrlr_tmp; struct spdk_nvme_ctrlr *ctrlr, *ctrlr_tmp;
if (!spdk_process_is_primary() && probe_ctx->trid.trtype == SPDK_NVME_TRANSPORT_PCIE) { if (!spdk_process_is_primary() && probe_ctx->trid.trtype == SPDK_NVME_TRANSPORT_PCIE) {
@ -1554,19 +1558,15 @@ spdk_nvme_probe_poll_async(struct spdk_nvme_probe_ctx *probe_ctx)
} }
TAILQ_FOREACH_SAFE(ctrlr, &probe_ctx->init_ctrlrs, tailq, ctrlr_tmp) { TAILQ_FOREACH_SAFE(ctrlr, &probe_ctx->init_ctrlrs, tailq, ctrlr_tmp) {
rc = nvme_ctrlr_poll_internal(ctrlr, probe_ctx); nvme_ctrlr_poll_internal(ctrlr, probe_ctx);
if (rc != 0) {
rc = -EIO;
break;
}
} }
if (rc != 0 || TAILQ_EMPTY(&probe_ctx->init_ctrlrs)) { if (TAILQ_EMPTY(&probe_ctx->init_ctrlrs)) {
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
g_spdk_nvme_driver->initialized = true; g_spdk_nvme_driver->initialized = true;
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
free(probe_ctx); free(probe_ctx);
return rc; return 0;
} }
return -EAGAIN; return -EAGAIN;

View File

@ -3445,7 +3445,7 @@ union spdk_nvme_csts_register spdk_nvme_ctrlr_get_regs_csts(struct spdk_nvme_ctr
union spdk_nvme_csts_register csts; union spdk_nvme_csts_register csts;
if (nvme_ctrlr_get_csts(ctrlr, &csts)) { if (nvme_ctrlr_get_csts(ctrlr, &csts)) {
csts.raw = 0xFFFFFFFFu; csts.raw = SPDK_NVME_INVALID_REGISTER_VALUE;
} }
return csts; return csts;
} }

View File

@ -191,6 +191,9 @@ extern pid_t g_spdk_nvme_pid;
#define NVME_FABRIC_CONNECT_COMMAND_TIMEOUT 500000 #define NVME_FABRIC_CONNECT_COMMAND_TIMEOUT 500000
#endif #endif
/* This value indicates that a read from a PCIe register is invalid. This can happen when a device is no longer present */
#define SPDK_NVME_INVALID_REGISTER_VALUE 0xFFFFFFFFu
enum nvme_payload_type { enum nvme_payload_type {
NVME_PAYLOAD_TYPE_INVALID = 0, NVME_PAYLOAD_TYPE_INVALID = 0,

View File

@ -667,7 +667,7 @@ nvme_qpair_resubmit_requests(struct spdk_nvme_qpair *qpair, uint32_t num_request
STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq); STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq);
resubmit_rc = nvme_qpair_resubmit_request(qpair, req); resubmit_rc = nvme_qpair_resubmit_request(qpair, req);
if (spdk_unlikely(resubmit_rc != 0)) { if (spdk_unlikely(resubmit_rc != 0)) {
SPDK_ERRLOG("Unable to resubmit as many requests as we completed.\n"); SPDK_DEBUGLOG(nvme, "Unable to resubmit as many requests as we completed.\n");
break; break;
} }
} }

View File

@ -57,7 +57,6 @@
#define NVME_TCP_HPDA_DEFAULT 0 #define NVME_TCP_HPDA_DEFAULT 0
#define NVME_TCP_MAX_R2T_DEFAULT 1 #define NVME_TCP_MAX_R2T_DEFAULT 1
#define NVME_TCP_PDU_H2C_MIN_DATA_SIZE 4096 #define NVME_TCP_PDU_H2C_MIN_DATA_SIZE 4096
#define NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE 8192
/* NVMe TCP transport extensions for spdk_nvme_ctrlr */ /* NVMe TCP transport extensions for spdk_nvme_ctrlr */
struct nvme_tcp_ctrlr { struct nvme_tcp_ctrlr {
@ -518,7 +517,7 @@ nvme_tcp_req_init(struct nvme_tcp_qpair *tqpair, struct nvme_request *req,
if (xfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER) { if (xfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER) {
max_incapsule_data_size = ctrlr->ioccsz_bytes; max_incapsule_data_size = ctrlr->ioccsz_bytes;
if ((req->cmd.opc == SPDK_NVME_OPC_FABRIC) || nvme_qpair_is_admin_queue(&tqpair->qpair)) { if ((req->cmd.opc == SPDK_NVME_OPC_FABRIC) || nvme_qpair_is_admin_queue(&tqpair->qpair)) {
max_incapsule_data_size = NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE; max_incapsule_data_size = SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE;
} }
if (req->payload_size <= max_incapsule_data_size) { if (req->payload_size <= max_incapsule_data_size) {
@ -990,13 +989,13 @@ nvme_tcp_send_icreq_complete(void *cb_arg)
{ {
struct nvme_tcp_qpair *tqpair = cb_arg; struct nvme_tcp_qpair *tqpair = cb_arg;
SPDK_DEBUGLOG(nvme, "Complete the icreq send for tqpair=%p\n", tqpair); SPDK_DEBUGLOG(nvme, "Complete the icreq send for tqpair=%p %u\n", tqpair, tqpair->qpair.id);
tqpair->flags.icreq_send_ack = true; tqpair->flags.icreq_send_ack = true;
if (tqpair->state == NVME_TCP_QPAIR_STATE_INITIALIZING) { if (tqpair->state == NVME_TCP_QPAIR_STATE_INITIALIZING) {
SPDK_DEBUGLOG(nvme, "qpair %u, finilize icresp\n", tqpair->qpair.id); SPDK_DEBUGLOG(nvme, "tqpair %p %u, finilize icresp\n", tqpair, tqpair->qpair.id);
nvme_tcp_icresp_handle(tqpair, &tqpair->recv_pdu); tqpair->state = NVME_TCP_QPAIR_STATE_RUNNING;
} }
} }
@ -1009,12 +1008,6 @@ nvme_tcp_icresp_handle(struct nvme_tcp_qpair *tqpair,
enum spdk_nvme_tcp_term_req_fes fes; enum spdk_nvme_tcp_term_req_fes fes;
int recv_buf_size; int recv_buf_size;
if (!tqpair->flags.icreq_send_ack) {
tqpair->state = NVME_TCP_QPAIR_STATE_INITIALIZING;
SPDK_DEBUGLOG(nvme, "qpair %u, waiting icreq ack\n", tqpair->qpair.id);
return;
}
/* Only PFV 0 is defined currently */ /* Only PFV 0 is defined currently */
if (ic_resp->pfv != 0) { if (ic_resp->pfv != 0) {
SPDK_ERRLOG("Expected ICResp PFV %u, got %u\n", 0u, ic_resp->pfv); SPDK_ERRLOG("Expected ICResp PFV %u, got %u\n", 0u, ic_resp->pfv);
@ -1065,8 +1058,15 @@ nvme_tcp_icresp_handle(struct nvme_tcp_qpair *tqpair,
/* Not fatal. */ /* Not fatal. */
} }
tqpair->state = NVME_TCP_QPAIR_STATE_RUNNING;
nvme_tcp_qpair_set_recv_state(tqpair, NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_READY); nvme_tcp_qpair_set_recv_state(tqpair, NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_READY);
if (!tqpair->flags.icreq_send_ack) {
tqpair->state = NVME_TCP_QPAIR_STATE_INITIALIZING;
SPDK_DEBUGLOG(nvme, "tqpair %p %u, waiting icreq ack\n", tqpair, tqpair->qpair.id);
return;
}
tqpair->state = NVME_TCP_QPAIR_STATE_RUNNING;
return; return;
end: end:
nvme_tcp_qpair_send_h2c_term_req(tqpair, pdu, fes, error_offset); nvme_tcp_qpair_send_h2c_term_req(tqpair, pdu, fes, error_offset);

View File

@ -814,6 +814,10 @@ nvmf_ctrlr_cc_shn_done(struct spdk_io_channel_iter *i, int status)
/* After CC.EN transitions to 0 (due to shutdown or reset), the association /* After CC.EN transitions to 0 (due to shutdown or reset), the association
* between the host and controller shall be preserved for at least 2 minutes */ * between the host and controller shall be preserved for at least 2 minutes */
if (ctrlr->association_timer) {
SPDK_DEBUGLOG(nvmf, "Association timer already set\n");
nvmf_ctrlr_stop_association_timer(ctrlr);
}
ctrlr->association_timer = SPDK_POLLER_REGISTER(nvmf_ctrlr_association_remove, ctrlr, ctrlr->association_timer = SPDK_POLLER_REGISTER(nvmf_ctrlr_association_remove, ctrlr,
ctrlr->admin_qpair->transport->opts.association_timeout * 1000); ctrlr->admin_qpair->transport->opts.association_timeout * 1000);
} }
@ -834,6 +838,10 @@ nvmf_ctrlr_cc_reset_done(struct spdk_io_channel_iter *i, int status)
/* After CC.EN transitions to 0 (due to shutdown or reset), the association /* After CC.EN transitions to 0 (due to shutdown or reset), the association
* between the host and controller shall be preserved for at least 2 minutes */ * between the host and controller shall be preserved for at least 2 minutes */
if (ctrlr->association_timer) {
SPDK_DEBUGLOG(nvmf, "Association timer already set\n");
nvmf_ctrlr_stop_association_timer(ctrlr);
}
ctrlr->association_timer = SPDK_POLLER_REGISTER(nvmf_ctrlr_association_remove, ctrlr, ctrlr->association_timer = SPDK_POLLER_REGISTER(nvmf_ctrlr_association_remove, ctrlr,
ctrlr->admin_qpair->transport->opts.association_timeout * 1000); ctrlr->admin_qpair->transport->opts.association_timeout * 1000);
} }

View File

@ -37,14 +37,14 @@
#include "spdk/assert.h" #include "spdk/assert.h"
#include "spdk/thread.h" #include "spdk/thread.h"
#include "spdk/nvmf_transport.h" #include "spdk/nvmf_transport.h"
#include "spdk/sock.h"
#include "spdk/string.h" #include "spdk/string.h"
#include "spdk/trace.h" #include "spdk/trace.h"
#include "spdk/util.h" #include "spdk/util.h"
#include "spdk/log.h"
#include "spdk_internal/assert.h" #include "spdk_internal/assert.h"
#include "spdk/log.h"
#include "spdk_internal/nvme_tcp.h" #include "spdk_internal/nvme_tcp.h"
#include "spdk_internal/sock.h"
#include "nvmf_internal.h" #include "nvmf_internal.h"
@ -254,12 +254,23 @@ struct spdk_nvmf_tcp_qpair {
TAILQ_ENTRY(spdk_nvmf_tcp_qpair) link; TAILQ_ENTRY(spdk_nvmf_tcp_qpair) link;
}; };
struct spdk_nvmf_tcp_control_msg {
STAILQ_ENTRY(spdk_nvmf_tcp_control_msg) link;
};
struct spdk_nvmf_tcp_control_msg_list {
void *msg_buf;
STAILQ_HEAD(, spdk_nvmf_tcp_control_msg) free_msgs;
};
struct spdk_nvmf_tcp_poll_group { struct spdk_nvmf_tcp_poll_group {
struct spdk_nvmf_transport_poll_group group; struct spdk_nvmf_transport_poll_group group;
struct spdk_sock_group *sock_group; struct spdk_sock_group *sock_group;
TAILQ_HEAD(, spdk_nvmf_tcp_qpair) qpairs; TAILQ_HEAD(, spdk_nvmf_tcp_qpair) qpairs;
TAILQ_HEAD(, spdk_nvmf_tcp_qpair) await_req; TAILQ_HEAD(, spdk_nvmf_tcp_qpair) await_req;
struct spdk_nvmf_tcp_control_msg_list *control_msg_list;
}; };
struct spdk_nvmf_tcp_port { struct spdk_nvmf_tcp_port {
@ -295,6 +306,7 @@ static const struct spdk_json_object_decoder tcp_transport_opts_decoder[] = {
static bool nvmf_tcp_req_process(struct spdk_nvmf_tcp_transport *ttransport, static bool nvmf_tcp_req_process(struct spdk_nvmf_tcp_transport *ttransport,
struct spdk_nvmf_tcp_req *tcp_req); struct spdk_nvmf_tcp_req *tcp_req);
static void nvmf_tcp_poll_group_destroy(struct spdk_nvmf_transport_poll_group *group);
static void static void
nvmf_tcp_req_set_state(struct spdk_nvmf_tcp_req *tcp_req, nvmf_tcp_req_set_state(struct spdk_nvmf_tcp_req *tcp_req,
@ -1001,6 +1013,49 @@ nvmf_tcp_discover(struct spdk_nvmf_transport *transport,
entry->tsas.tcp.sectype = SPDK_NVME_TCP_SECURITY_NONE; entry->tsas.tcp.sectype = SPDK_NVME_TCP_SECURITY_NONE;
} }
static struct spdk_nvmf_tcp_control_msg_list *
nvmf_tcp_control_msg_list_create(uint16_t num_messages)
{
struct spdk_nvmf_tcp_control_msg_list *list;
struct spdk_nvmf_tcp_control_msg *msg;
uint16_t i;
list = calloc(1, sizeof(*list));
if (!list) {
SPDK_ERRLOG("Failed to allocate memory for list structure\n");
return NULL;
}
list->msg_buf = spdk_zmalloc(num_messages * SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE,
NVMF_DATA_BUFFER_ALIGNMENT, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA);
if (!list->msg_buf) {
SPDK_ERRLOG("Failed to allocate memory for control message buffers\n");
free(list);
return NULL;
}
STAILQ_INIT(&list->free_msgs);
for (i = 0; i < num_messages; i++) {
msg = (struct spdk_nvmf_tcp_control_msg *)((char *)list->msg_buf + i *
SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE);
STAILQ_INSERT_TAIL(&list->free_msgs, msg, link);
}
return list;
}
static void
nvmf_tcp_control_msg_list_free(struct spdk_nvmf_tcp_control_msg_list *list)
{
if (!list) {
return;
}
spdk_free(list->msg_buf);
free(list);
}
static struct spdk_nvmf_transport_poll_group * static struct spdk_nvmf_transport_poll_group *
nvmf_tcp_poll_group_create(struct spdk_nvmf_transport *transport) nvmf_tcp_poll_group_create(struct spdk_nvmf_transport *transport)
{ {
@ -1019,10 +1074,20 @@ nvmf_tcp_poll_group_create(struct spdk_nvmf_transport *transport)
TAILQ_INIT(&tgroup->qpairs); TAILQ_INIT(&tgroup->qpairs);
TAILQ_INIT(&tgroup->await_req); TAILQ_INIT(&tgroup->await_req);
if (transport->opts.in_capsule_data_size < SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE) {
SPDK_DEBUGLOG(nvmf_tcp, "ICD %u is less than min required for admin/fabric commands (%u). "
"Creating control messages list\n", transport->opts.in_capsule_data_size,
SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE);
tgroup->control_msg_list = nvmf_tcp_control_msg_list_create(32);
if (!tgroup->control_msg_list) {
goto cleanup;
}
}
return &tgroup->group; return &tgroup->group;
cleanup: cleanup:
free(tgroup); nvmf_tcp_poll_group_destroy(&tgroup->group);
return NULL; return NULL;
} }
@ -1049,6 +1114,9 @@ nvmf_tcp_poll_group_destroy(struct spdk_nvmf_transport_poll_group *group)
tgroup = SPDK_CONTAINEROF(group, struct spdk_nvmf_tcp_poll_group, group); tgroup = SPDK_CONTAINEROF(group, struct spdk_nvmf_tcp_poll_group, group);
spdk_sock_group_close(&tgroup->sock_group); spdk_sock_group_close(&tgroup->sock_group);
if (tgroup->control_msg_list) {
nvmf_tcp_control_msg_list_free(tgroup->control_msg_list);
}
free(tgroup); free(tgroup);
} }
@ -1556,6 +1624,7 @@ nvmf_tcp_icreq_handle(struct spdk_nvmf_tcp_transport *ttransport,
tqpair->recv_buf_size -= SPDK_NVME_TCP_DIGEST_LEN * SPDK_NVMF_TCP_RECV_BUF_SIZE_FACTOR; tqpair->recv_buf_size -= SPDK_NVME_TCP_DIGEST_LEN * SPDK_NVMF_TCP_RECV_BUF_SIZE_FACTOR;
} }
tqpair->recv_buf_size = spdk_max(tqpair->recv_buf_size, MIN_SOCK_PIPE_SIZE);
/* Now that we know whether digests are enabled, properly size the receive buffer */ /* Now that we know whether digests are enabled, properly size the receive buffer */
if (spdk_sock_set_recvbuf(tqpair->sock, tqpair->recv_buf_size) < 0) { if (spdk_sock_set_recvbuf(tqpair->sock, tqpair->recv_buf_size) < 0) {
SPDK_WARNLOG("Unable to allocate enough memory for receive buffer on tqpair=%p with size=%d\n", SPDK_WARNLOG("Unable to allocate enough memory for receive buffer on tqpair=%p with size=%d\n",
@ -1867,6 +1936,31 @@ nvmf_tcp_sock_process(struct spdk_nvmf_tcp_qpair *tqpair)
return rc; return rc;
} }
static inline void *
nvmf_tcp_control_msg_get(struct spdk_nvmf_tcp_control_msg_list *list)
{
struct spdk_nvmf_tcp_control_msg *msg;
assert(list);
msg = STAILQ_FIRST(&list->free_msgs);
if (!msg) {
SPDK_DEBUGLOG(nvmf_tcp, "Out of control messages\n");
return NULL;
}
STAILQ_REMOVE_HEAD(&list->free_msgs, link);
return msg;
}
static inline void
nvmf_tcp_control_msg_put(struct spdk_nvmf_tcp_control_msg_list *list, void *_msg)
{
struct spdk_nvmf_tcp_control_msg *msg = _msg;
assert(list);
STAILQ_INSERT_HEAD(&list->free_msgs, msg, link);
}
static int static int
nvmf_tcp_req_parse_sgl(struct spdk_nvmf_tcp_req *tcp_req, nvmf_tcp_req_parse_sgl(struct spdk_nvmf_tcp_req *tcp_req,
struct spdk_nvmf_transport *transport, struct spdk_nvmf_transport *transport,
@ -1876,6 +1970,7 @@ nvmf_tcp_req_parse_sgl(struct spdk_nvmf_tcp_req *tcp_req,
struct spdk_nvme_cmd *cmd; struct spdk_nvme_cmd *cmd;
struct spdk_nvme_cpl *rsp; struct spdk_nvme_cpl *rsp;
struct spdk_nvme_sgl_descriptor *sgl; struct spdk_nvme_sgl_descriptor *sgl;
struct spdk_nvmf_tcp_poll_group *tgroup;
uint32_t length; uint32_t length;
cmd = &req->cmd->nvme_cmd; cmd = &req->cmd->nvme_cmd;
@ -1922,6 +2017,7 @@ nvmf_tcp_req_parse_sgl(struct spdk_nvmf_tcp_req *tcp_req,
sgl->unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET) { sgl->unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET) {
uint64_t offset = sgl->address; uint64_t offset = sgl->address;
uint32_t max_len = transport->opts.in_capsule_data_size; uint32_t max_len = transport->opts.in_capsule_data_size;
assert(tcp_req->has_incapsule_data);
SPDK_DEBUGLOG(nvmf_tcp, "In-capsule data: offset 0x%" PRIx64 ", length 0x%x\n", SPDK_DEBUGLOG(nvmf_tcp, "In-capsule data: offset 0x%" PRIx64 ", length 0x%x\n",
offset, length); offset, length);
@ -1934,16 +2030,33 @@ nvmf_tcp_req_parse_sgl(struct spdk_nvmf_tcp_req *tcp_req,
} }
max_len -= (uint32_t)offset; max_len -= (uint32_t)offset;
if (length > max_len) { if (spdk_unlikely(length > max_len)) {
SPDK_ERRLOG("In-capsule data length 0x%x exceeds capsule length 0x%x\n", /* According to the SPEC we should support ICD up to 8192 bytes for admin and fabric commands */
length, max_len); if (length <= SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE &&
rsp->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID; (cmd->opc == SPDK_NVME_OPC_FABRIC || req->qpair->qid == 0)) {
return -1;
/* Get a buffer from dedicated list */
SPDK_DEBUGLOG(nvmf_tcp, "Getting a buffer from control msg list\n");
tgroup = SPDK_CONTAINEROF(group, struct spdk_nvmf_tcp_poll_group, group);
assert(tgroup->control_msg_list);
req->data = nvmf_tcp_control_msg_get(tgroup->control_msg_list);
if (!req->data) {
/* No available buffers. Queue this request up. */
SPDK_DEBUGLOG(nvmf_tcp, "No available ICD buffers. Queueing request %p\n", tcp_req);
return 0;
}
} else {
SPDK_ERRLOG("In-capsule data length 0x%x exceeds capsule length 0x%x\n",
length, max_len);
rsp->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID;
return -1;
}
} else {
req->data = tcp_req->buf;
} }
req->data = tcp_req->buf + offset;
req->data_from_pool = false;
req->length = length; req->length = length;
req->data_from_pool = false;
if (spdk_unlikely(req->dif.dif_insert_or_strip)) { if (spdk_unlikely(req->dif.dif_insert_or_strip)) {
length = spdk_dif_get_length_with_md(length, &req->dif.dif_ctx); length = spdk_dif_get_length_with_md(length, &req->dif.dif_ctx);
@ -2130,6 +2243,7 @@ nvmf_tcp_req_process(struct spdk_nvmf_tcp_transport *ttransport,
bool progress = false; bool progress = false;
struct spdk_nvmf_transport *transport = &ttransport->transport; struct spdk_nvmf_transport *transport = &ttransport->transport;
struct spdk_nvmf_transport_poll_group *group; struct spdk_nvmf_transport_poll_group *group;
struct spdk_nvmf_tcp_poll_group *tgroup;
tqpair = SPDK_CONTAINEROF(tcp_req->req.qpair, struct spdk_nvmf_tcp_qpair, qpair); tqpair = SPDK_CONTAINEROF(tcp_req->req.qpair, struct spdk_nvmf_tcp_qpair, qpair);
group = &tqpair->group->group; group = &tqpair->group->group;
@ -2301,6 +2415,12 @@ nvmf_tcp_req_process(struct spdk_nvmf_tcp_transport *ttransport,
spdk_trace_record(TRACE_TCP_REQUEST_STATE_COMPLETED, 0, 0, (uintptr_t)tcp_req, 0); spdk_trace_record(TRACE_TCP_REQUEST_STATE_COMPLETED, 0, 0, (uintptr_t)tcp_req, 0);
if (tcp_req->req.data_from_pool) { if (tcp_req->req.data_from_pool) {
spdk_nvmf_request_free_buffers(&tcp_req->req, group, transport); spdk_nvmf_request_free_buffers(&tcp_req->req, group, transport);
} else if (spdk_unlikely(tcp_req->has_incapsule_data && (tcp_req->cmd.opc == SPDK_NVME_OPC_FABRIC ||
tqpair->qpair.qid == 0) && tcp_req->req.length > transport->opts.in_capsule_data_size)) {
tgroup = SPDK_CONTAINEROF(group, struct spdk_nvmf_tcp_poll_group, group);
assert(tgroup->control_msg_list);
SPDK_DEBUGLOG(nvmf_tcp, "Put buf to control msg list\n");
nvmf_tcp_control_msg_put(tgroup->control_msg_list, tcp_req->req.data);
} }
tcp_req->req.length = 0; tcp_req->req.length = 0;
tcp_req->req.iovcnt = 0; tcp_req->req.iovcnt = 0;

View File

@ -663,8 +663,8 @@ fs_load_cb(__attribute__((unused)) void *ctx,
} }
static void static void
base_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, base_bdev_event_cb(enum spdk_bdev_event_type type, __attribute__((unused)) struct spdk_bdev *bdev,
void *event_ctx) __attribute__((unused)) void *event_ctx)
{ {
printf("Unsupported bdev event: type %d\n", type); printf("Unsupported bdev event: type %d\n", type);
} }

View File

@ -56,7 +56,6 @@ endif
SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST = $(ALL_MODULES_LIST)
SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM) SPDK_LIB_LIST += $(EVENT_BDEV_SUBSYSTEM)
SPDK_LIB_LIST += bdev accel event util conf trace log jsonrpc json rpc sock thread notify SPDK_LIB_LIST += bdev accel event util conf trace log jsonrpc json rpc sock thread notify
SPDK_LIB_LIST += blobfs_bdev
AM_LINK += $(SPDK_LIB_LINKER_ARGS) $(ENV_LINKER_ARGS) AM_LINK += $(SPDK_LIB_LINKER_ARGS) $(ENV_LINKER_ARGS)
AM_LINK += $(SYS_LIBS) AM_LINK += $(SYS_LIBS)

View File

@ -500,6 +500,7 @@ msg_queue_run_batch(struct spdk_thread *thread, uint32_t max_msgs)
unsigned count, i; unsigned count, i;
void *messages[SPDK_MSG_BATCH_SIZE]; void *messages[SPDK_MSG_BATCH_SIZE];
uint64_t notify = 1; uint64_t notify = 1;
int rc;
#ifdef DEBUG #ifdef DEBUG
/* /*
@ -520,12 +521,18 @@ msg_queue_run_batch(struct spdk_thread *thread, uint32_t max_msgs)
* so msg_acknowledge should be applied ahead. And then check for self's msg_notify. * so msg_acknowledge should be applied ahead. And then check for self's msg_notify.
* This can avoid msg notification missing. * This can avoid msg notification missing.
*/ */
read(thread->msg_fd, &notify, sizeof(notify)); rc = read(thread->msg_fd, &notify, sizeof(notify));
if (rc < 0) {
SPDK_ERRLOG("failed to acknowledge msg_queue: %s.\n", spdk_strerror(errno));
}
} }
count = spdk_ring_dequeue(thread->messages, messages, max_msgs); count = spdk_ring_dequeue(thread->messages, messages, max_msgs);
if (thread->interrupt_mode && spdk_ring_count(thread->messages) != 0) { if (thread->interrupt_mode && spdk_ring_count(thread->messages) != 0) {
write(thread->msg_fd, &notify, sizeof(notify)); rc = write(thread->msg_fd, &notify, sizeof(notify));
if (rc < 0) {
SPDK_ERRLOG("failed to notify msg_queue: %s.\n", spdk_strerror(errno));
}
} }
if (count == 0) { if (count == 0) {
return 0; return 0;
@ -917,7 +924,11 @@ spdk_thread_send_msg(const struct spdk_thread *thread, spdk_msg_fn fn, void *ctx
if (thread->interrupt_mode) { if (thread->interrupt_mode) {
uint64_t notify = 1; uint64_t notify = 1;
write(thread->msg_fd, &notify, sizeof(notify)); rc = write(thread->msg_fd, &notify, sizeof(notify));
if (rc < 0) {
SPDK_ERRLOG("failed to notify msg_queue: %s.\n", spdk_strerror(errno));
return -EIO;
}
} }
return 0; return 0;
@ -932,8 +943,13 @@ spdk_thread_send_critical_msg(struct spdk_thread *thread, spdk_msg_fn fn)
__ATOMIC_SEQ_CST)) { __ATOMIC_SEQ_CST)) {
if (thread->interrupt_mode) { if (thread->interrupt_mode) {
uint64_t notify = 1; uint64_t notify = 1;
int rc;
write(thread->msg_fd, &notify, sizeof(notify)); rc = write(thread->msg_fd, &notify, sizeof(notify));
if (rc < 0) {
SPDK_ERRLOG("failed to notify msg_queue: %s.\n", spdk_strerror(errno));
return -EIO;
}
} }
return 0; return 0;

View File

@ -382,7 +382,8 @@ bdev_aio_group_interrupt(void *arg)
if (num_events > SPDK_AIO_QUEUE_DEPTH) { if (num_events > SPDK_AIO_QUEUE_DEPTH) {
num_events -= SPDK_AIO_QUEUE_DEPTH; num_events -= SPDK_AIO_QUEUE_DEPTH;
if (write(group_ch->efd, &num_events, sizeof(num_events))) { rc = write(group_ch->efd, &num_events, sizeof(num_events));
if (rc < 0) {
SPDK_ERRLOG("failed to notify aio group: %s.\n", spdk_strerror(errno)); SPDK_ERRLOG("failed to notify aio group: %s.\n", spdk_strerror(errno));
} }
} }

View File

@ -81,7 +81,7 @@ static struct spdk_sock_impl_opts g_spdk_posix_sock_impl_opts = {
.recv_buf_size = MIN_SO_RCVBUF_SIZE, .recv_buf_size = MIN_SO_RCVBUF_SIZE,
.send_buf_size = MIN_SO_SNDBUF_SIZE, .send_buf_size = MIN_SO_SNDBUF_SIZE,
.enable_recv_pipe = true, .enable_recv_pipe = true,
.enable_zerocopy_send = true, .enable_zerocopy_send = false,
.enable_quickack = false, .enable_quickack = false,
.enable_placement_id = false, .enable_placement_id = false,
}; };

View File

@ -2,12 +2,12 @@
%bcond_with doc %bcond_with doc
Name: spdk Name: spdk
Version: master Version: 20.10.x
Release: 0%{?dist} Release: 0%{?dist}
Epoch: 0 Epoch: 0
URL: http://spdk.io URL: http://spdk.io
Source: https://github.com/spdk/spdk/archive/master.tar.gz Source: https://github.com/spdk/spdk/archive/v20.10.x.tar.gz
Summary: Set of libraries and utilities for high performance user-mode storage Summary: Set of libraries and utilities for high performance user-mode storage
%define package_version %{epoch}:%{version}-%{release} %define package_version %{epoch}:%{version}-%{release}

View File

@ -152,7 +152,7 @@ parser.add_argument('-d', '--max-disks', default=0, type=int,
each virtual machine gets it's own bdev to work on.") each virtual machine gets it's own bdev to work on.")
parser.add_argument('-v', '--vm-count', default=1, type=int, parser.add_argument('-v', '--vm-count', default=1, type=int,
help="How many VMs to run in test. Default: 1") help="How many VMs to run in test. Default: 1")
parser.add_argument('-i', '--vm-image', default="$HOME/vhost_vm_image.qcow2", parser.add_argument('-i', '--vm-image', default="$HOME/spdk_test_image.qcow2",
type=str, help="VM image to use for running VMs.") type=str, help="VM image to use for running VMs.")
subparsers = parser.add_subparsers() subparsers = parser.add_subparsers()

View File

@ -146,7 +146,7 @@ def nvmf_create_transport(client,
params['max_qpairs_per_ctrlr'] = max_qpairs_per_ctrlr params['max_qpairs_per_ctrlr'] = max_qpairs_per_ctrlr
if max_io_qpairs_per_ctrlr: if max_io_qpairs_per_ctrlr:
params['max_io_qpairs_per_ctrlr'] = max_io_qpairs_per_ctrlr params['max_io_qpairs_per_ctrlr'] = max_io_qpairs_per_ctrlr
if in_capsule_data_size: if in_capsule_data_size is not None:
params['in_capsule_data_size'] = in_capsule_data_size params['in_capsule_data_size'] = in_capsule_data_size
if max_io_size: if max_io_size:
params['max_io_size'] = max_io_size params['max_io_size'] = max_io_size
@ -156,7 +156,7 @@ def nvmf_create_transport(client,
params['max_aq_depth'] = max_aq_depth params['max_aq_depth'] = max_aq_depth
if num_shared_buffers: if num_shared_buffers:
params['num_shared_buffers'] = num_shared_buffers params['num_shared_buffers'] = num_shared_buffers
if buf_cache_size: if buf_cache_size is not None:
params['buf_cache_size'] = buf_cache_size params['buf_cache_size'] = buf_cache_size
if max_srq_depth: if max_srq_depth:
params['max_srq_depth'] = max_srq_depth params['max_srq_depth'] = max_srq_depth
@ -166,7 +166,7 @@ def nvmf_create_transport(client,
params['c2h_success'] = c2h_success params['c2h_success'] = c2h_success
if dif_insert_or_strip: if dif_insert_or_strip:
params['dif_insert_or_strip'] = dif_insert_or_strip params['dif_insert_or_strip'] = dif_insert_or_strip
if sock_priority: if sock_priority is not None:
params['sock_priority'] = sock_priority params['sock_priority'] = sock_priority
if acceptor_backlog is not None: if acceptor_backlog is not None:
params['acceptor_backlog'] = acceptor_backlog params['acceptor_backlog'] = acceptor_backlog
@ -254,7 +254,7 @@ def nvmf_create_subsystem(client,
if allow_any_host: if allow_any_host:
params['allow_any_host'] = True params['allow_any_host'] = True
if max_namespaces: if max_namespaces is not None:
params['max_namespaces'] = max_namespaces params['max_namespaces'] = max_namespaces
if tgt_name: if tgt_name:

View File

@ -31,43 +31,40 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #
DPDK_LIB = -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf -lrte_mempool_ring -lrte_pci
DPDK_LIB += -lrte_bus_pci -lrte_kvargs -lrte_vhost -lrte_net -lrte_hash -lrte_telemetry
DPDK_LIB += -lrte_cryptodev -lrte_power -lrte_rcu
# Shows how to compile both an external bdev and an external application against the SPDK combined shared object and dpdk shared objects. # Shows how to compile both an external bdev and an external application against the SPDK combined shared object and dpdk shared objects.
bdev_shared_combo: bdev_shared_combo:
$(CC) $(COMMON_CFLAGS) -L../passthru -Wl,-rpath=$(SPDK_LIB_DIR),--no-as-needed -o hello_bdev ./hello_bdev.c -lpassthru_external \ $(CC) $(COMMON_CFLAGS) -L../passthru -Wl,-rpath=$(SPDK_LIB_DIR),--no-as-needed -o hello_bdev ./hello_bdev.c -lpassthru_external \
-lspdk -lspdk_env_dpdk -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf -lrte_mempool_ring -lrte_pci -lrte_bus_pci -lrte_kvargs \ -lspdk -lspdk_env_dpdk $(DPDK_LIB) -Wl,--no-whole-archive
-lrte_vhost -lrte_net -lrte_hash -lrte_cryptodev -lrte_power -Wl,--no-whole-archive
# Shows how to compile both an external bdev and an external application against the SPDK individual shared objects and dpdk shared objects. # Shows how to compile both an external bdev and an external application against the SPDK individual shared objects and dpdk shared objects.
bdev_shared_iso: bdev_shared_iso:
$(CC) $(COMMON_CFLAGS) -L../passthru -Wl,-rpath=$(SPDK_LIB_DIR),--no-as-needed -o hello_bdev ./hello_bdev.c \ $(CC) $(COMMON_CFLAGS) -L../passthru -Wl,-rpath=$(SPDK_LIB_DIR),--no-as-needed -o hello_bdev ./hello_bdev.c \
-lpassthru_external -lspdk_event_bdev -lspdk_event_accel -lspdk_event_vmd -lspdk_bdev -lspdk_bdev_malloc -lspdk_log -lspdk_thread -lspdk_util -lspdk_event \ -lpassthru_external -lspdk_event_bdev -lspdk_event_accel -lspdk_event_vmd -lspdk_bdev -lspdk_bdev_malloc -lspdk_log -lspdk_thread -lspdk_util -lspdk_event \
-lspdk_env_dpdk -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf -lrte_mempool_ring -lrte_pci -lrte_bus_pci -lrte_kvargs \ -lspdk_env_dpdk $(DPDK_LIB) -Wl,--no-whole-archive -lnuma
-lrte_vhost -lrte_net -lrte_hash -lrte_cryptodev -lrte_power -Wl,--no-whole-archive -lnuma
# Shows how to compile an external application against the SPDK combined shared object and dpdk shared objects. # Shows how to compile an external application against the SPDK combined shared object and dpdk shared objects.
alone_shared_combo: alone_shared_combo:
$(CC) $(COMMON_CFLAGS) -Wl,-rpath=$(SPDK_LIB_DIR),--no-as-needed -o hello_bdev ./hello_bdev.c -lspdk -lspdk_env_dpdk -lrte_eal \ $(CC) $(COMMON_CFLAGS) -Wl,-rpath=$(SPDK_LIB_DIR),--no-as-needed -o hello_bdev ./hello_bdev.c -lspdk -lspdk_env_dpdk $(DPDK_LIB)
-lrte_mempool -lrte_ring -lrte_mbuf -lrte_mempool_ring -lrte_pci -lrte_bus_pci -lrte_kvargs -lrte_vhost -lrte_net -lrte_hash -lrte_cryptodev -lrte_power
# Shows how to compile an external application against the SPDK individual shared objects and dpdk shared objects. # Shows how to compile an external application against the SPDK individual shared objects and dpdk shared objects.
alone_shared_iso: alone_shared_iso:
$(CC) $(COMMON_CFLAGS) -Wl,-rpath=$(SPDK_LIB_DIR),--no-as-needed -o hello_bdev ./hello_bdev.c -lspdk_event_bdev \ $(CC) $(COMMON_CFLAGS) -Wl,-rpath=$(SPDK_LIB_DIR),--no-as-needed -o hello_bdev ./hello_bdev.c -lspdk_event_bdev \
-lspdk_event_accel -lspdk_event_vmd -lspdk_bdev -lspdk_bdev_malloc -lspdk_log -lspdk_thread -lspdk_util -lspdk_event \ -lspdk_event_accel -lspdk_event_vmd -lspdk_bdev -lspdk_bdev_malloc -lspdk_log -lspdk_thread -lspdk_util -lspdk_event -lspdk_env_dpdk $(DPDK_LIB)
-lspdk_env_dpdk -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf -lrte_mempool_ring -lrte_pci -lrte_bus_pci -lrte_kvargs \
-lrte_vhost -lrte_net -lrte_hash -lrte_cryptodev -lrte_power
# Shows how to compile an external application against the SPDK archives. # Shows how to compile an external application against the SPDK archives.
alone_static: alone_static:
$(CC) $(COMMON_CFLAGS) -o hello_bdev ./hello_bdev.c -Wl,--whole-archive,-Bstatic -lspdk_bdev_malloc -lspdk_event_bdev -lspdk_event_accel -lspdk_event_vmd \ $(CC) $(COMMON_CFLAGS) -o hello_bdev ./hello_bdev.c -Wl,--whole-archive,-Bstatic -lspdk_bdev_malloc -lspdk_event_bdev -lspdk_event_accel -lspdk_event_vmd \
-lspdk_event_sock -lspdk_bdev -lspdk_accel -lspdk_event -lspdk_thread -lspdk_util -lspdk_conf -lspdk_trace -lspdk_log -lspdk_json \ -lspdk_event_sock -lspdk_bdev -lspdk_accel -lspdk_event -lspdk_thread -lspdk_util -lspdk_conf -lspdk_trace -lspdk_log -lspdk_json \
-lspdk_jsonrpc -lspdk_rpc -lspdk_sock -lspdk_notify -lspdk_vmd -lspdk_env_dpdk -lrte_eal -lrte_mempool -lrte_ring \ -lspdk_jsonrpc -lspdk_rpc -lspdk_sock -lspdk_notify -lspdk_vmd -lspdk_env_dpdk \
-lrte_mbuf -lrte_mempool_ring -lrte_pci -lrte_bus_pci -lrte_kvargs -lrte_vhost -lrte_net -lrte_hash -lrte_telemetry \ $(DPDK_LIB) -Wl,--no-whole-archive,-Bdynamic -lnuma -luuid -lpthread -ldl -lrt
-lrte_cryptodev -lrte_power -Wl,--no-whole-archive,-Bdynamic -lnuma -luuid -lpthread -ldl -lrt
# Shows how to compile and external bdev and application sgainst the SPDK archives. # Shows how to compile and external bdev and application sgainst the SPDK archives.
bdev_static: bdev_static:
$(CC) $(COMMON_CFLAGS) -L../passthru -o hello_bdev ./hello_bdev.c -Wl,--whole-archive,-Bstatic -lpassthru_external -lspdk_bdev_malloc -lspdk_event_bdev \ $(CC) $(COMMON_CFLAGS) -L../passthru -o hello_bdev ./hello_bdev.c -Wl,--whole-archive,-Bstatic -lpassthru_external -lspdk_bdev_malloc -lspdk_event_bdev \
-lspdk_event_accel -lspdk_event_vmd -lspdk_event_sock -lspdk_bdev -lspdk_accel -lspdk_event -lspdk_thread -lspdk_util -lspdk_conf -lspdk_trace \ -lspdk_event_accel -lspdk_event_vmd -lspdk_event_sock -lspdk_bdev -lspdk_accel -lspdk_event -lspdk_thread -lspdk_util -lspdk_conf -lspdk_trace \
-lspdk_log -lspdk_json -lspdk_jsonrpc -lspdk_rpc -lspdk_sock -lspdk_notify -lspdk_vmd -lspdk_env_dpdk -lrte_eal -lrte_mempool \ -lspdk_log -lspdk_json -lspdk_jsonrpc -lspdk_rpc -lspdk_sock -lspdk_notify -lspdk_vmd -lspdk_env_dpdk $(DPDK_LIB) \
-lrte_ring -lrte_mbuf -lrte_mempool_ring -lrte_pci -lrte_bus_pci -lrte_kvargs -lrte_vhost -lrte_net -lrte_hash -lrte_telemetry -lrte_cryptodev \ -Wl,--no-whole-archive,-Bdynamic -lnuma -luuid -lpthread -ldl -lrt
-lrte_power -Wl,--no-whole-archive,-Bdynamic -lnuma -luuid -lpthread -ldl -lrt

View File

@ -54,9 +54,8 @@ function devices_delete() {
} }
password=$1 password=$1
base_img=${DEPENDENCY_DIR}/fedora-hotplug.qcow2 base_img=$HOME/spdk_test_image.qcow2
test_img=${DEPENDENCY_DIR}/fedora-hotplug-test.qcow2 qemu_pidfile=$HOME/qemupid
qemu_pidfile=${DEPENDENCY_DIR}/qemupid
if [ ! -e "$base_img" ]; then if [ ! -e "$base_img" ]; then
echo "Hotplug VM image not found; skipping test" echo "Hotplug VM image not found; skipping test"
@ -65,8 +64,6 @@ fi
timing_enter start_qemu timing_enter start_qemu
qemu-img create -b "$base_img" -f qcow2 "$test_img"
for i in {0..3}; do for i in {0..3}; do
dd if=/dev/zero of="$SPDK_TEST_STORAGE/nvme$i.img" bs=1M count=1024 dd if=/dev/zero of="$SPDK_TEST_STORAGE/nvme$i.img" bs=1M count=1024
done done
@ -74,7 +71,7 @@ done
qemu-system-x86_64 \ qemu-system-x86_64 \
-daemonize -display none -m 8192 \ -daemonize -display none -m 8192 \
-pidfile "$qemu_pidfile" \ -pidfile "$qemu_pidfile" \
-hda "$test_img" \ -hda "$base_img" \
-net user,hostfwd=tcp::10022-:22 \ -net user,hostfwd=tcp::10022-:22 \
-net nic \ -net nic \
-cpu host \ -cpu host \
@ -85,7 +82,8 @@ qemu-system-x86_64 \
-drive format=raw,file="$SPDK_TEST_STORAGE/nvme0.img",if=none,id=drive0 \ -drive format=raw,file="$SPDK_TEST_STORAGE/nvme0.img",if=none,id=drive0 \
-drive format=raw,file="$SPDK_TEST_STORAGE/nvme1.img",if=none,id=drive1 \ -drive format=raw,file="$SPDK_TEST_STORAGE/nvme1.img",if=none,id=drive1 \
-drive format=raw,file="$SPDK_TEST_STORAGE/nvme2.img",if=none,id=drive2 \ -drive format=raw,file="$SPDK_TEST_STORAGE/nvme2.img",if=none,id=drive2 \
-drive format=raw,file="$SPDK_TEST_STORAGE/nvme3.img",if=none,id=drive3 -drive format=raw,file="$SPDK_TEST_STORAGE/nvme3.img",if=none,id=drive3 \
-snapshot
timing_exit start_qemu timing_exit start_qemu
@ -98,7 +96,15 @@ files_to_copy="scripts "
files_to_copy+="include/spdk/pci_ids.h " files_to_copy+="include/spdk/pci_ids.h "
files_to_copy+="build/examples/hotplug " files_to_copy+="build/examples/hotplug "
files_to_copy+="build/lib " files_to_copy+="build/lib "
files_to_copy+="dpdk/build/lib "
# Select which dpdk libs to copy in case we're not building with
# spdk/dpdk submodule
if [[ -n "$SPDK_RUN_EXTERNAL_DPDK" ]]; then
files_to_copy+="-C $SPDK_RUN_EXTERNAL_DPDK/../.. dpdk/build/lib"
else
files_to_copy+="dpdk/build/lib "
fi
( (
cd "$rootdir" cd "$rootdir"
tar -cf - $files_to_copy tar -cf - $files_to_copy
@ -129,6 +135,5 @@ trap - SIGINT SIGTERM EXIT
qemupid=$(awk '{printf $0}' "$qemu_pidfile") qemupid=$(awk '{printf $0}' "$qemu_pidfile")
kill -9 $qemupid kill -9 $qemupid
rm "$qemu_pidfile" rm "$qemu_pidfile"
rm "$test_img"
timing_exit hotplug_test timing_exit hotplug_test

View File

@ -91,6 +91,13 @@ nvme_ctrlr_destruct_poll_async(struct spdk_nvme_ctrlr *ctrlr,
return 0; return 0;
} }
union spdk_nvme_csts_register
spdk_nvme_ctrlr_get_regs_csts(struct spdk_nvme_ctrlr *ctrlr)
{
union spdk_nvme_csts_register csts = {};
return csts;
}
void void
spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t opts_size) spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t opts_size)
{ {
@ -382,7 +389,7 @@ test_nvme_init_controllers(void)
probe_ctx->attach_cb = attach_cb; probe_ctx->attach_cb = attach_cb;
probe_ctx->trid.trtype = SPDK_NVME_TRANSPORT_PCIE; probe_ctx->trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
rc = nvme_init_controllers(probe_ctx); rc = nvme_init_controllers(probe_ctx);
CU_ASSERT(rc != 0); CU_ASSERT(rc == 0);
CU_ASSERT(g_spdk_nvme_driver->initialized == true); CU_ASSERT(g_spdk_nvme_driver->initialized == true);
CU_ASSERT(ut_destruct_called == true); CU_ASSERT(ut_destruct_called == true);
@ -1270,9 +1277,13 @@ static void
test_nvme_wait_for_completion(void) test_nvme_wait_for_completion(void)
{ {
struct spdk_nvme_qpair qpair; struct spdk_nvme_qpair qpair;
struct spdk_nvme_ctrlr ctrlr;
int rc = 0; int rc = 0;
memset(&ctrlr, 0, sizeof(ctrlr));
ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
memset(&qpair, 0, sizeof(qpair)); memset(&qpair, 0, sizeof(qpair));
qpair.ctrlr = &ctrlr;
/* completion timeout */ /* completion timeout */
memset(&g_status, 0, sizeof(g_status)); memset(&g_status, 0, sizeof(g_status));

View File

@ -44,6 +44,8 @@ bool trace_flag = false;
#include "nvme/nvme_qpair.c" #include "nvme/nvme_qpair.c"
SPDK_LOG_REGISTER_COMPONENT(nvme)
struct nvme_driver _g_nvme_driver = { struct nvme_driver _g_nvme_driver = {
.lock = PTHREAD_MUTEX_INITIALIZER, .lock = PTHREAD_MUTEX_INITIALIZER,
}; };

View File

@ -459,6 +459,7 @@ test_nvmf_tcp_poll_group_create(void)
{ {
struct spdk_nvmf_transport *transport; struct spdk_nvmf_transport *transport;
struct spdk_nvmf_transport_poll_group *group; struct spdk_nvmf_transport_poll_group *group;
struct spdk_nvmf_tcp_poll_group *tgroup;
struct spdk_thread *thread; struct spdk_thread *thread;
struct spdk_nvmf_transport_opts opts; struct spdk_nvmf_transport_opts opts;
struct spdk_sock_group grp = {}; struct spdk_sock_group grp = {};
@ -482,6 +483,10 @@ test_nvmf_tcp_poll_group_create(void)
group = nvmf_tcp_poll_group_create(transport); group = nvmf_tcp_poll_group_create(transport);
MOCK_CLEAR_P(spdk_sock_group_create); MOCK_CLEAR_P(spdk_sock_group_create);
SPDK_CU_ASSERT_FATAL(group); SPDK_CU_ASSERT_FATAL(group);
if (opts.in_capsule_data_size < SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE) {
tgroup = SPDK_CONTAINEROF(group, struct spdk_nvmf_tcp_poll_group, group);
SPDK_CU_ASSERT_FATAL(tgroup->control_msg_list);
}
group->transport = transport; group->transport = transport;
nvmf_tcp_poll_group_destroy(group); nvmf_tcp_poll_group_destroy(group);
nvmf_tcp_destroy(transport); nvmf_tcp_destroy(transport);

View File

@ -8,8 +8,7 @@ VM_DIR=$VHOST_DIR/vms
TARGET_DIR=$VHOST_DIR/vhost TARGET_DIR=$VHOST_DIR/vhost
VM_PASSWORD="root" VM_PASSWORD="root"
#TODO: Move vhost_vm_image.qcow2 into VHOST_DIR on test systems. VM_IMAGE=$HOME/spdk_test_image.qcow2
VM_IMAGE=$HOME/vhost_vm_image.qcow2
if ! hash $QEMU_IMG_BIN $QEMU_BIN; then if ! hash $QEMU_IMG_BIN $QEMU_BIN; then
error 'QEMU is not installed on this system. Unable to run vhost tests.' error 'QEMU is not installed on this system. Unable to run vhost tests.'

View File

@ -21,7 +21,7 @@ case $1 in
echo " -h |--help prints this message" echo " -h |--help prints this message"
echo "" echo ""
echo "Environment:" echo "Environment:"
echo " VM_IMAGE path to QCOW2 VM image used during test (default: $HOME/vhost_vm_image.qcow2)" echo " VM_IMAGE path to QCOW2 VM image used during test (default: $HOME/spdk_test_image.qcow2)"
echo "" echo ""
echo "Tests are performed only on Linux machine. For other OS no action is performed." echo "Tests are performed only on Linux machine. For other OS no action is performed."
echo "" echo ""

View File

@ -53,7 +53,7 @@ function usage() {
echo " --vm-memory=INT Amount of RAM memory (in MB) to pass to a single VM." echo " --vm-memory=INT Amount of RAM memory (in MB) to pass to a single VM."
echo " Default: 2048 MB" echo " Default: 2048 MB"
echo " --vm-image=PATH OS image to use for running the VMs." echo " --vm-image=PATH OS image to use for running the VMs."
echo " Default: \$HOME/vhost_vm_image.qcow2" echo " Default: \$HOME/spdk_test_image.qcow2"
echo " --vm-sar-enable Measure CPU utilization in guest VMs using sar." echo " --vm-sar-enable Measure CPU utilization in guest VMs using sar."
echo " --host-sar-enable Measure CPU utilization on host using sar." echo " --host-sar-enable Measure CPU utilization on host using sar."
echo " --sar-delay=INT Wait for X seconds before starting SAR measurement. Default: 0." echo " --sar-delay=INT Wait for X seconds before starting SAR measurement. Default: 0."