@@ -2015,21 +2015,51 @@ static void nvme_configure_metadata(struct nvme_ctrl *ctrl,
2015
2015
}
2016
2016
2017
2017
2018
- static void nvme_update_atomic_write_disk_info (struct nvme_ns * ns ,
2019
- struct nvme_id_ns * id , struct queue_limits * lim ,
2020
- u32 bs , u32 atomic_bs )
2018
+ static u32 nvme_configure_atomic_write (struct nvme_ns * ns ,
2019
+ struct nvme_id_ns * id , struct queue_limits * lim , u32 bs )
2021
2020
{
2022
- unsigned int boundary = 0 ;
2021
+ u32 atomic_bs , boundary = 0 ;
2023
2022
2024
- if (id -> nsfeat & NVME_NS_FEAT_ATOMICS && id -> nawupf ) {
2025
- if (le16_to_cpu (id -> nabspf ))
2023
+ /*
2024
+ * We do not support an offset for the atomic boundaries.
2025
+ */
2026
+ if (id -> nabo )
2027
+ return bs ;
2028
+
2029
+ if ((id -> nsfeat & NVME_NS_FEAT_ATOMICS ) && id -> nawupf ) {
2030
+ /*
2031
+ * Use the per-namespace atomic write unit when available.
2032
+ */
2033
+ atomic_bs = (1 + le16_to_cpu (id -> nawupf )) * bs ;
2034
+ if (id -> nabspf )
2026
2035
boundary = (le16_to_cpu (id -> nabspf ) + 1 ) * bs ;
2036
+ } else {
2037
+ /*
2038
+ * Use the controller wide atomic write unit. This sucks
2039
+ * because the limit is defined in terms of logical blocks while
2040
+ * namespaces can have different formats, and because there is
2041
+ * no clear language in the specification prohibiting different
2042
+ * values for different controllers in the subsystem.
2043
+ */
2044
+ atomic_bs = (1 + ns -> ctrl -> awupf ) * bs ;
2045
+ }
2046
+
2047
+ if (!ns -> ctrl -> subsys -> atomic_bs ) {
2048
+ ns -> ctrl -> subsys -> atomic_bs = atomic_bs ;
2049
+ } else if (ns -> ctrl -> subsys -> atomic_bs != atomic_bs ) {
2050
+ dev_err_ratelimited (ns -> ctrl -> device ,
2051
+ "%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n" ,
2052
+ ns -> disk ? ns -> disk -> disk_name : "?" ,
2053
+ ns -> ctrl -> subsys -> atomic_bs ,
2054
+ atomic_bs );
2027
2055
}
2056
+
2028
2057
lim -> atomic_write_hw_max = atomic_bs ;
2029
2058
lim -> atomic_write_hw_boundary = boundary ;
2030
2059
lim -> atomic_write_hw_unit_min = bs ;
2031
2060
lim -> atomic_write_hw_unit_max = rounddown_pow_of_two (atomic_bs );
2032
2061
lim -> features |= BLK_FEAT_ATOMIC_WRITES ;
2062
+ return atomic_bs ;
2033
2063
}
2034
2064
2035
2065
static u32 nvme_max_drv_segments (struct nvme_ctrl * ctrl )
@@ -2067,34 +2097,8 @@ static bool nvme_update_disk_info(struct nvme_ns *ns, struct nvme_id_ns *id,
2067
2097
valid = false;
2068
2098
}
2069
2099
2070
- atomic_bs = phys_bs = bs ;
2071
- if (id -> nabo == 0 ) {
2072
- /*
2073
- * Bit 1 indicates whether NAWUPF is defined for this namespace
2074
- * and whether it should be used instead of AWUPF. If NAWUPF ==
2075
- * 0 then AWUPF must be used instead.
2076
- */
2077
- if (id -> nsfeat & NVME_NS_FEAT_ATOMICS && id -> nawupf )
2078
- atomic_bs = (1 + le16_to_cpu (id -> nawupf )) * bs ;
2079
- else
2080
- atomic_bs = (1 + ns -> ctrl -> awupf ) * bs ;
2081
-
2082
- /*
2083
- * Set subsystem atomic bs.
2084
- */
2085
- if (ns -> ctrl -> subsys -> atomic_bs ) {
2086
- if (atomic_bs != ns -> ctrl -> subsys -> atomic_bs ) {
2087
- dev_err_ratelimited (ns -> ctrl -> device ,
2088
- "%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n" ,
2089
- ns -> disk ? ns -> disk -> disk_name : "?" ,
2090
- ns -> ctrl -> subsys -> atomic_bs ,
2091
- atomic_bs );
2092
- }
2093
- } else
2094
- ns -> ctrl -> subsys -> atomic_bs = atomic_bs ;
2095
-
2096
- nvme_update_atomic_write_disk_info (ns , id , lim , bs , atomic_bs );
2097
- }
2100
+ phys_bs = bs ;
2101
+ atomic_bs = nvme_configure_atomic_write (ns , id , lim , bs );
2098
2102
2099
2103
if (id -> nsfeat & NVME_NS_FEAT_IO_OPT ) {
2100
2104
/* NPWG = Namespace Preferred Write Granularity */
0 commit comments