[PATCH v3 0/7] Enable DSM pass thru for root functions
by Jerry Hoemann
The ACPI 6.2 spec added NVDIMM root DSM functions that managibility
and test software need to call.
This patch set enables the calling of root functions DSMs via the
pass thru mechanism.
Changes v3
----------
1. Fix checkpatch warnings
2. modify bus_dsm_mask_show to display name "dsm_mask" in sysfs.
3. modified submittal comments.
Changes v2
----------
1. Add bus_dsm_mask to filter root pass thru calls.
2. Add bus_dsm_mask_show to display bus_dsm_mask in sysfs
3. Extend override_dsm_mask to be used for bus_dms_mask also.
Details v1
----------
__nd_ioctl:
Check pass thru functions against nd_cmd_clear_to_send.
acpi_nfit_init_dsms:
Set additional bits in cmd_mask for new functions.
ndctl.h:
Define data structure for the new 6.2 functions.
Jerry Hoemann (7):
libnvdimm: passthru functions clear to send
acpi, nfit: Enable DSM pass thru for root functions.
libnvdimm: Add bus level dsm mask.
acpi, nfit: Use bus_dsm_mask for passthru
acpi, nfit: Show bus_dsm_mask in sysfs
libnvdimm: New ACPI 6.2 DSM functions
acpi, nfit: override mask
drivers/acpi/nfit/core.c | 23 +++++++++++++++++++++++
drivers/nvdimm/bus.c | 4 +++-
include/linux/libnvdimm.h | 1 +
include/uapi/linux/ndctl.h | 41 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 67 insertions(+), 2 deletions(-)
--
1.8.5.6
3 years, 6 months
[PATCH] acpi, nfit: quiet invalid block-aperture-region warnings
by Dan Williams
This state is already visible by userspace since the BLK region will not
be enabled, and it is otherwise benign as it usually indicates that the
DIMM is not configured.
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
drivers/nvdimm/region_devs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index 282b8991ea83..ab141f8b5140 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -833,7 +833,7 @@ int nd_blk_region_init(struct nd_region *nd_region)
return 0;
if (nd_region->ndr_mappings < 1) {
- dev_err(dev, "invalid BLK region\n");
+ dev_dbg(dev, "invalid BLK region\n");
return -ENXIO;
}
3 years, 6 months
[ndctl PATCH] Documentation: refactor ndctl and daxctl man pages into respective sub-directories
by Dan Williams
The manpage template has global references to the base utility name.
This leads to the header for daxctl having the following header and
footer:
DAXCTL(1) ndctl Manual DAXCTL(1)
ndctl 57.9.g3d9a255 06/28/2017 DAXCTL(1)
The 'ndctl' references should say 'daxctl'.
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
Documentation/asciidoc.conf.in | 24 +++++++--------
Documentation/daxctl/Makefile.am | 38 +++++++++++++++++++++++
Documentation/daxctl/daxctl-list.txt | 0
Documentation/daxctl/daxctl.txt | 4 +-
Documentation/ndctl/Makefile.am | 14 +++++---
Documentation/ndctl/dimm-description.txt | 0
Documentation/ndctl/labels-description.txt | 0
Documentation/ndctl/labels-options.txt | 0
Documentation/ndctl/namespace-description.txt | 0
Documentation/ndctl/ndctl-check-labels.txt | 0
Documentation/ndctl/ndctl-check-namespace.txt | 0
Documentation/ndctl/ndctl-create-namespace.txt | 0
Documentation/ndctl/ndctl-destroy-namespace.txt | 0
Documentation/ndctl/ndctl-disable-dimm.txt | 0
Documentation/ndctl/ndctl-disable-namespace.txt | 0
Documentation/ndctl/ndctl-disable-region.txt | 0
Documentation/ndctl/ndctl-enable-dimm.txt | 0
Documentation/ndctl/ndctl-enable-namespace.txt | 0
Documentation/ndctl/ndctl-enable-region.txt | 0
Documentation/ndctl/ndctl-init-labels.txt | 0
Documentation/ndctl/ndctl-list.txt | 0
Documentation/ndctl/ndctl-read-labels.txt | 0
Documentation/ndctl/ndctl-write-labels.txt | 0
Documentation/ndctl/ndctl-zero-labels.txt | 0
Documentation/ndctl/ndctl.txt | 0
Documentation/ndctl/region-description.txt | 0
Documentation/ndctl/xable-dimm-options.txt | 0
Documentation/ndctl/xable-namespace-options.txt | 0
Documentation/ndctl/xable-region-options.txt | 0
Makefile.am | 2 +
configure.ac | 3 +-
31 files changed, 64 insertions(+), 21 deletions(-)
rename Documentation/{asciidoc.conf => asciidoc.conf.in} (79%)
create mode 100644 Documentation/daxctl/Makefile.am
rename Documentation/{daxctl-list.txt => daxctl/daxctl-list.txt} (100%)
rename Documentation/{daxctl.txt => daxctl/daxctl.txt} (89%)
rename Documentation/{Makefile.am => ndctl/Makefile.am} (86%)
rename Documentation/{dimm-description.txt => ndctl/dimm-description.txt} (100%)
rename Documentation/{labels-description.txt => ndctl/labels-description.txt} (100%)
rename Documentation/{labels-options.txt => ndctl/labels-options.txt} (100%)
rename Documentation/{namespace-description.txt => ndctl/namespace-description.txt} (100%)
rename Documentation/{ndctl-check-labels.txt => ndctl/ndctl-check-labels.txt} (100%)
rename Documentation/{ndctl-check-namespace.txt => ndctl/ndctl-check-namespace.txt} (100%)
rename Documentation/{ndctl-create-namespace.txt => ndctl/ndctl-create-namespace.txt} (100%)
rename Documentation/{ndctl-destroy-namespace.txt => ndctl/ndctl-destroy-namespace.txt} (100%)
rename Documentation/{ndctl-disable-dimm.txt => ndctl/ndctl-disable-dimm.txt} (100%)
rename Documentation/{ndctl-disable-namespace.txt => ndctl/ndctl-disable-namespace.txt} (100%)
rename Documentation/{ndctl-disable-region.txt => ndctl/ndctl-disable-region.txt} (100%)
rename Documentation/{ndctl-enable-dimm.txt => ndctl/ndctl-enable-dimm.txt} (100%)
rename Documentation/{ndctl-enable-namespace.txt => ndctl/ndctl-enable-namespace.txt} (100%)
rename Documentation/{ndctl-enable-region.txt => ndctl/ndctl-enable-region.txt} (100%)
rename Documentation/{ndctl-init-labels.txt => ndctl/ndctl-init-labels.txt} (100%)
rename Documentation/{ndctl-list.txt => ndctl/ndctl-list.txt} (100%)
rename Documentation/{ndctl-read-labels.txt => ndctl/ndctl-read-labels.txt} (100%)
rename Documentation/{ndctl-write-labels.txt => ndctl/ndctl-write-labels.txt} (100%)
rename Documentation/{ndctl-zero-labels.txt => ndctl/ndctl-zero-labels.txt} (100%)
rename Documentation/{ndctl.txt => ndctl/ndctl.txt} (100%)
rename Documentation/{region-description.txt => ndctl/region-description.txt} (100%)
rename Documentation/{xable-dimm-options.txt => ndctl/xable-dimm-options.txt} (100%)
rename Documentation/{xable-namespace-options.txt => ndctl/xable-namespace-options.txt} (100%)
rename Documentation/{xable-region-options.txt => ndctl/xable-region-options.txt} (100%)
diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf.in
similarity index 79%
rename from Documentation/asciidoc.conf
rename to Documentation/asciidoc.conf.in
index 8c6ee4672c30..5a1f056761b9 100644
--- a/Documentation/asciidoc.conf
+++ b/Documentation/asciidoc.conf.in
@@ -1,4 +1,4 @@
-## linkndctl: macro
+## linkUTILITY: macro
#
# Copyright (c) 2005, Sergey Vlasov
# Copyright (c) 2005, Jonas Fonseca
@@ -6,7 +6,7 @@
# Originally copied from GIT source (commit d1c2e113c5b6 "[PATCH]
# Documentation: Add asciidoc.conf file and gitlink: macro")
#
-# Usage: linkndctl:command[manpage-section]
+# Usage: linkUTILITY:command[manpage-section]
#
# Note, {0} is the manpage section, while {target} is the command.
#
@@ -14,7 +14,7 @@
# the command.
[macros]
-(?su)[\\]?(?P<name>linkndctl):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
+(?su)[\\]?(?P<name>linkUTILITY):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
[attributes]
asterisk=*
@@ -25,7 +25,7 @@ endsb=]
tilde=~
ifdef::backend-docbook[]
-[linkndctl-inlinemacro]
+[linkUTILITY-inlinemacro]
{0%{target}}
{0#<citerefentry>}
{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
@@ -33,7 +33,7 @@ ifdef::backend-docbook[]
endif::backend-docbook[]
ifdef::backend-docbook[]
-ifndef::ndctl-asciidoc-no-roff[]
+ifndef::UTILITY-asciidoc-no-roff[]
# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this.
# v1.72 breaks with this because it replaces dots not in roff requests.
[listingblock]
@@ -48,9 +48,9 @@ ifdef::doctype-manpage[]
endif::doctype-manpage[]
</literallayout>
{title#}</example>
-endif::ndctl-asciidoc-no-roff[]
+endif::UTILITY-asciidoc-no-roff[]
-ifdef::ndctl-asciidoc-no-roff[]
+ifdef::UTILITY-asciidoc-no-roff[]
ifdef::doctype-manpage[]
# The following two small workarounds insert a simple paragraph after screen
[listingblock]
@@ -69,7 +69,7 @@ ifdef::doctype-manpage[]
{title#}</para></formalpara>
{title%}<simpara></simpara>
endif::doctype-manpage[]
-endif::ndctl-asciidoc-no-roff[]
+endif::UTILITY-asciidoc-no-roff[]
endif::backend-docbook[]
ifdef::doctype-manpage[]
@@ -80,9 +80,9 @@ template::[header-declarations]
<refmeta>
<refentrytitle>{mantitle}</refentrytitle>
<manvolnum>{manvolnum}</manvolnum>
-<refmiscinfo class="source">ndctl</refmiscinfo>
-<refmiscinfo class="version">{ndctl_version}</refmiscinfo>
-<refmiscinfo class="manual">ndctl Manual</refmiscinfo>
+<refmiscinfo class="source">UTILITY</refmiscinfo>
+<refmiscinfo class="version">{UTILITY_version}</refmiscinfo>
+<refmiscinfo class="manual">UTILITY Manual</refmiscinfo>
</refmeta>
<refnamediv>
<refname>{manname}</refname>
@@ -92,6 +92,6 @@ endif::backend-docbook[]
endif::doctype-manpage[]
ifdef::backend-xhtml11[]
-[linkndctl-inlinemacro]
+[linkUTILITY-inlinemacro]
<a href="{target}.html">{target}{0?({0})}</a>
endif::backend-xhtml11[]
diff --git a/Documentation/daxctl/Makefile.am b/Documentation/daxctl/Makefile.am
new file mode 100644
index 000000000000..5913c94ca3be
--- /dev/null
+++ b/Documentation/daxctl/Makefile.am
@@ -0,0 +1,38 @@
+# Copyright(c) 2015-2017 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+do_subst = sed -e 's,UTILITY,daxctl,g'
+
+asciidoc.conf: ../asciidoc.conf.in
+ $(AM_V_GEN) $(do_subst) < $< > $@
+
+man1_MANS = \
+ daxctl.1 \
+ daxctl-list.1
+
+CLEANFILES = $(man1_MANS)
+
+XML_DEPS = \
+ ../../version.m4 \
+ Makefile \
+ asciidoc.conf
+
+RM ?= rm -f
+
+%.xml: %.txt $(XML_DEPS)
+ $(AM_V_GEN)$(RM) $@+ $@ && \
+ $(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \
+ --unsafe -adaxctl_version=$(VERSION) -o $@+ $< && \
+ mv $@+ $@
+
+%.1: %.xml
+ $(AM_V_GEN)$(RM) $@ && \
+ $(XMLTO) -o . -m ../manpage-normal.xsl man $<
diff --git a/Documentation/daxctl-list.txt b/Documentation/daxctl/daxctl-list.txt
similarity index 100%
rename from Documentation/daxctl-list.txt
rename to Documentation/daxctl/daxctl-list.txt
diff --git a/Documentation/daxctl.txt b/Documentation/daxctl/daxctl.txt
similarity index 89%
rename from Documentation/daxctl.txt
rename to Documentation/daxctl/daxctl.txt
index 5e81b33fd24f..5da9746ea62a 100644
--- a/Documentation/daxctl.txt
+++ b/Documentation/daxctl/daxctl.txt
@@ -29,5 +29,5 @@ filesystem.
SEE ALSO
--------
-linkndctl:ndctl-create-namespace[1],
-linkndctl:ndctl-list[1]
+linkdaxctl:ndctl-create-namespace[1],
+linkdaxctl:ndctl-list[1]
diff --git a/Documentation/Makefile.am b/Documentation/ndctl/Makefile.am
similarity index 86%
rename from Documentation/Makefile.am
rename to Documentation/ndctl/Makefile.am
index a56c4f0e8888..229d9087bbd5 100644
--- a/Documentation/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -9,8 +9,12 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
+do_subst = sed -e 's,UTILITY,ndctl,g'
+
+asciidoc.conf: ../asciidoc.conf.in
+ $(AM_V_GEN) $(do_subst) < $< > $@
+
man1_MANS = \
- daxctl.1 \
ndctl.1 \
ndctl-zero-labels.1 \
ndctl-read-labels.1 \
@@ -26,14 +30,14 @@ man1_MANS = \
ndctl-create-namespace.1 \
ndctl-destroy-namespace.1 \
ndctl-check-namespace.1 \
- ndctl-list.1 \
- daxctl-list.1
+ ndctl-list.1
CLEANFILES = $(man1_MANS)
XML_DEPS = \
- ..//version.m4 \
+ ../../version.m4 \
Makefile \
+ asciidoc.conf \
region-description.txt \
xable-region-options.txt \
dimm-description.txt \
@@ -52,4 +56,4 @@ RM ?= rm -f
%.1: %.xml
$(AM_V_GEN)$(RM) $@ && \
- $(XMLTO) -o . -m manpage-normal.xsl man $<
+ $(XMLTO) -o . -m ../manpage-normal.xsl man $<
diff --git a/Documentation/dimm-description.txt b/Documentation/ndctl/dimm-description.txt
similarity index 100%
rename from Documentation/dimm-description.txt
rename to Documentation/ndctl/dimm-description.txt
diff --git a/Documentation/labels-description.txt b/Documentation/ndctl/labels-description.txt
similarity index 100%
rename from Documentation/labels-description.txt
rename to Documentation/ndctl/labels-description.txt
diff --git a/Documentation/labels-options.txt b/Documentation/ndctl/labels-options.txt
similarity index 100%
rename from Documentation/labels-options.txt
rename to Documentation/ndctl/labels-options.txt
diff --git a/Documentation/namespace-description.txt b/Documentation/ndctl/namespace-description.txt
similarity index 100%
rename from Documentation/namespace-description.txt
rename to Documentation/ndctl/namespace-description.txt
diff --git a/Documentation/ndctl-check-labels.txt b/Documentation/ndctl/ndctl-check-labels.txt
similarity index 100%
rename from Documentation/ndctl-check-labels.txt
rename to Documentation/ndctl/ndctl-check-labels.txt
diff --git a/Documentation/ndctl-check-namespace.txt b/Documentation/ndctl/ndctl-check-namespace.txt
similarity index 100%
rename from Documentation/ndctl-check-namespace.txt
rename to Documentation/ndctl/ndctl-check-namespace.txt
diff --git a/Documentation/ndctl-create-namespace.txt b/Documentation/ndctl/ndctl-create-namespace.txt
similarity index 100%
rename from Documentation/ndctl-create-namespace.txt
rename to Documentation/ndctl/ndctl-create-namespace.txt
diff --git a/Documentation/ndctl-destroy-namespace.txt b/Documentation/ndctl/ndctl-destroy-namespace.txt
similarity index 100%
rename from Documentation/ndctl-destroy-namespace.txt
rename to Documentation/ndctl/ndctl-destroy-namespace.txt
diff --git a/Documentation/ndctl-disable-dimm.txt b/Documentation/ndctl/ndctl-disable-dimm.txt
similarity index 100%
rename from Documentation/ndctl-disable-dimm.txt
rename to Documentation/ndctl/ndctl-disable-dimm.txt
diff --git a/Documentation/ndctl-disable-namespace.txt b/Documentation/ndctl/ndctl-disable-namespace.txt
similarity index 100%
rename from Documentation/ndctl-disable-namespace.txt
rename to Documentation/ndctl/ndctl-disable-namespace.txt
diff --git a/Documentation/ndctl-disable-region.txt b/Documentation/ndctl/ndctl-disable-region.txt
similarity index 100%
rename from Documentation/ndctl-disable-region.txt
rename to Documentation/ndctl/ndctl-disable-region.txt
diff --git a/Documentation/ndctl-enable-dimm.txt b/Documentation/ndctl/ndctl-enable-dimm.txt
similarity index 100%
rename from Documentation/ndctl-enable-dimm.txt
rename to Documentation/ndctl/ndctl-enable-dimm.txt
diff --git a/Documentation/ndctl-enable-namespace.txt b/Documentation/ndctl/ndctl-enable-namespace.txt
similarity index 100%
rename from Documentation/ndctl-enable-namespace.txt
rename to Documentation/ndctl/ndctl-enable-namespace.txt
diff --git a/Documentation/ndctl-enable-region.txt b/Documentation/ndctl/ndctl-enable-region.txt
similarity index 100%
rename from Documentation/ndctl-enable-region.txt
rename to Documentation/ndctl/ndctl-enable-region.txt
diff --git a/Documentation/ndctl-init-labels.txt b/Documentation/ndctl/ndctl-init-labels.txt
similarity index 100%
rename from Documentation/ndctl-init-labels.txt
rename to Documentation/ndctl/ndctl-init-labels.txt
diff --git a/Documentation/ndctl-list.txt b/Documentation/ndctl/ndctl-list.txt
similarity index 100%
rename from Documentation/ndctl-list.txt
rename to Documentation/ndctl/ndctl-list.txt
diff --git a/Documentation/ndctl-read-labels.txt b/Documentation/ndctl/ndctl-read-labels.txt
similarity index 100%
rename from Documentation/ndctl-read-labels.txt
rename to Documentation/ndctl/ndctl-read-labels.txt
diff --git a/Documentation/ndctl-write-labels.txt b/Documentation/ndctl/ndctl-write-labels.txt
similarity index 100%
rename from Documentation/ndctl-write-labels.txt
rename to Documentation/ndctl/ndctl-write-labels.txt
diff --git a/Documentation/ndctl-zero-labels.txt b/Documentation/ndctl/ndctl-zero-labels.txt
similarity index 100%
rename from Documentation/ndctl-zero-labels.txt
rename to Documentation/ndctl/ndctl-zero-labels.txt
diff --git a/Documentation/ndctl.txt b/Documentation/ndctl/ndctl.txt
similarity index 100%
rename from Documentation/ndctl.txt
rename to Documentation/ndctl/ndctl.txt
diff --git a/Documentation/region-description.txt b/Documentation/ndctl/region-description.txt
similarity index 100%
rename from Documentation/region-description.txt
rename to Documentation/ndctl/region-description.txt
diff --git a/Documentation/xable-dimm-options.txt b/Documentation/ndctl/xable-dimm-options.txt
similarity index 100%
rename from Documentation/xable-dimm-options.txt
rename to Documentation/ndctl/xable-dimm-options.txt
diff --git a/Documentation/xable-namespace-options.txt b/Documentation/ndctl/xable-namespace-options.txt
similarity index 100%
rename from Documentation/xable-namespace-options.txt
rename to Documentation/ndctl/xable-namespace-options.txt
diff --git a/Documentation/xable-region-options.txt b/Documentation/ndctl/xable-region-options.txt
similarity index 100%
rename from Documentation/xable-region-options.txt
rename to Documentation/ndctl/xable-region-options.txt
diff --git a/Makefile.am b/Makefile.am
index 2b467362f55c..ba81e8c3d5bb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,7 @@ include Makefile.am.in
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
SUBDIRS = . daxctl/lib ndctl/lib ndctl daxctl
if ENABLE_DOCS
-SUBDIRS += Documentation
+SUBDIRS += Documentation/ndctl Documentation/daxctl
endif
SUBDIRS += test
diff --git a/configure.ac b/configure.ac
index e79623ac1d82..316f5b7c8b75 100644
--- a/configure.ac
+++ b/configure.ac
@@ -265,7 +265,8 @@ AC_CONFIG_FILES([
ndctl/Makefile
daxctl/Makefile
test/Makefile
- Documentation/Makefile
+ Documentation/ndctl/Makefile
+ Documentation/daxctl/Makefile
])
AC_OUTPUT
3 years, 6 months
[PATCH v2 0/7] Enable DSM pass thru for root functions
by Jerry Hoemann
The new ACPI 6.2 spec has added new NVDIMM root DSM functions
that managibility and test software needs to call.
This patch set enables the calling root functions DSM via the
pass thru mechanism.
Changes v2
----------
1. Add bus_dsm_mask to filter root pass thru calls.
2. Add bus_dsm_mask_show to display bus_dsm_mask in sysfs
3. Extend override_dsm_mask to be used for bus_dms_mask also.
Details v1
----------
__nd_ioctl:
Check pass thru functions against nd_cmd_clear_to_send.
acpi_nfit_init_dsms:
Set additional bits in cmd_mask for new functions.
ndctl.h:
Define data structure for the new 6.2 functions.
Add new function names to nvdimm_bus_cmd_name.
Jerry Hoemann (7):
libnvdimm: passthru functions clear to send
acpi, nfit: Enable DSM pass thru for root functions.
libnvdimm: Add bus level dsm mask.
acpi, nfit: Use bus_dsm_mask for passthru
acpi, nfit: Show bus_dsm_mask
libnvdimm: New ACPI 6.2 DSM functions
acpi, nfit: override mask
drivers/acpi/nfit/core.c | 20 ++++++++++++++++++++
drivers/nvdimm/bus.c | 4 +++-
include/linux/libnvdimm.h | 1 +
include/uapi/linux/ndctl.h | 41 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 64 insertions(+), 2 deletions(-)
--
1.8.5.6
3 years, 6 months
[PATCH v5] libnvdimm, btt: BTT updates for UEFI 2.7 format
by Vishal Verma
The UEFI 2.7 specification defines an updated BTT metadata format,
bumping the revision to 2.0. Add support for the new format, while
retaining compatibility for the old 1.1 format.
Cc: Toshi Kani <toshi.kani(a)hpe.com>
Cc: Linda Knippers <linda.knippers(a)hpe.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
v5:
- Correctly propagate the error return from btt_claim_class
v4:
- Fix up dereferencing of nd_region->mappings (Dan)
- Check all the mappings for label consistency (Dan)
- Refactor figuring out the BTT claim class into its own helper (Dan)
v3:
- Add athe actual BTT2 guid from the UEFI spec, and plumb a new
claim class for it (Dan)
v2:
- Don't enforce new BTTs being v2, base that decision on the holder class (Dan)
- Refactor nd_btt_version slightly, and get rid of the version enum.
drivers/nvdimm/btt.c | 28 +++++++++++++------
drivers/nvdimm/btt.h | 2 ++
drivers/nvdimm/btt_devs.c | 46 +++++++++++++++++++++++++++----
drivers/nvdimm/claim.c | 1 +
drivers/nvdimm/label.c | 6 ++++
drivers/nvdimm/label.h | 1 +
drivers/nvdimm/namespace_devs.c | 61 +++++++++++++++++++++++++++++++++++++++--
drivers/nvdimm/nd.h | 3 ++
include/linux/nd.h | 1 +
9 files changed, 134 insertions(+), 15 deletions(-)
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 983718b..7ca11df 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -37,8 +37,8 @@ static int arena_read_bytes(struct arena_info *arena, resource_size_t offset,
struct nd_btt *nd_btt = arena->nd_btt;
struct nd_namespace_common *ndns = nd_btt->ndns;
- /* arena offsets are 4K from the base of the device */
- offset += SZ_4K;
+ /* arena offsets may be shifted from the base of the device */
+ offset += arena->nd_btt->initial_offset;
return nvdimm_read_bytes(ndns, offset, buf, n, flags);
}
@@ -48,8 +48,8 @@ static int arena_write_bytes(struct arena_info *arena, resource_size_t offset,
struct nd_btt *nd_btt = arena->nd_btt;
struct nd_namespace_common *ndns = nd_btt->ndns;
- /* arena offsets are 4K from the base of the device */
- offset += SZ_4K;
+ /* arena offsets may be shifted from the base of the device */
+ offset += arena->nd_btt->initial_offset;
return nvdimm_write_bytes(ndns, offset, buf, n, flags);
}
@@ -576,8 +576,8 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size,
arena->internal_lbasize = roundup(arena->external_lbasize,
INT_LBASIZE_ALIGNMENT);
arena->nfree = BTT_DEFAULT_NFREE;
- arena->version_major = 1;
- arena->version_minor = 1;
+ arena->version_major = btt->nd_btt->version_major;
+ arena->version_minor = btt->nd_btt->version_minor;
if (available % BTT_PG_SIZE)
available -= (available % BTT_PG_SIZE);
@@ -1425,6 +1425,7 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns)
{
struct nd_btt *nd_btt = to_nd_btt(ndns->claim);
struct nd_region *nd_region;
+ struct btt_sb *btt_sb;
struct btt *btt;
size_t rawsize;
@@ -1433,10 +1434,21 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns)
return -ENODEV;
}
- rawsize = nvdimm_namespace_capacity(ndns) - SZ_4K;
+ btt_sb = devm_kzalloc(&nd_btt->dev, sizeof(*btt_sb), GFP_KERNEL);
+
+ /*
+ * If this returns < 0, that is ok as it just means there wasn't
+ * an existing BTT, and we're creating a new one. We still need to
+ * call this as we need the version dependent fields in nd_btt to be
+ * set correctly based on the holder class
+ */
+ nd_btt_version(nd_btt, ndns, btt_sb);
+
+ rawsize = nvdimm_namespace_capacity(ndns) - nd_btt->initial_offset;
if (rawsize < ARENA_MIN_SIZE) {
dev_dbg(&nd_btt->dev, "%s must be at least %ld bytes\n",
- dev_name(&ndns->dev), ARENA_MIN_SIZE + SZ_4K);
+ dev_name(&ndns->dev),
+ ARENA_MIN_SIZE + nd_btt->initial_offset);
return -ENXIO;
}
nd_region = to_nd_region(nd_btt->dev.parent);
diff --git a/drivers/nvdimm/btt.h b/drivers/nvdimm/btt.h
index b2f8651..888e862 100644
--- a/drivers/nvdimm/btt.h
+++ b/drivers/nvdimm/btt.h
@@ -184,5 +184,7 @@ struct btt {
};
bool nd_btt_arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super);
+int nd_btt_version(struct nd_btt *nd_btt, struct nd_namespace_common *ndns,
+ struct btt_sb *btt_sb);
#endif
diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c
index 31d875a..3e359d2 100644
--- a/drivers/nvdimm/btt_devs.c
+++ b/drivers/nvdimm/btt_devs.c
@@ -260,20 +260,55 @@ bool nd_btt_arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super)
}
EXPORT_SYMBOL(nd_btt_arena_is_valid);
+int nd_btt_version(struct nd_btt *nd_btt, struct nd_namespace_common *ndns,
+ struct btt_sb *btt_sb)
+{
+ if (ndns->claim_class == NVDIMM_CCLASS_BTT2) {
+ /* Probe/setup for BTT v2.0 */
+ nd_btt->initial_offset = 0;
+ nd_btt->version_major = 2;
+ nd_btt->version_minor = 0;
+ if (nvdimm_read_bytes(ndns, 0, btt_sb, sizeof(*btt_sb), 0))
+ return -ENXIO;
+ if (!nd_btt_arena_is_valid(nd_btt, btt_sb))
+ return -ENODEV;
+ if ((le16_to_cpu(btt_sb->version_major) != 2) ||
+ (le16_to_cpu(btt_sb->version_minor) != 0))
+ return -ENODEV;
+ } else {
+ /*
+ * Probe/setup for BTT v1.1 (NVDIMM_CCLASS_NONE or
+ * NVDIMM_CCLASS_BTT)
+ */
+ nd_btt->initial_offset = SZ_4K;
+ nd_btt->version_major = 1;
+ nd_btt->version_minor = 1;
+ if (nvdimm_read_bytes(ndns, SZ_4K, btt_sb, sizeof(*btt_sb), 0))
+ return -ENXIO;
+ if (!nd_btt_arena_is_valid(nd_btt, btt_sb))
+ return -ENODEV;
+ if ((le16_to_cpu(btt_sb->version_major) != 1) ||
+ (le16_to_cpu(btt_sb->version_minor) != 1))
+ return -ENODEV;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(nd_btt_version);
+
static int __nd_btt_probe(struct nd_btt *nd_btt,
struct nd_namespace_common *ndns, struct btt_sb *btt_sb)
{
+ int rc;
+
if (!btt_sb || !ndns || !nd_btt)
return -ENODEV;
- if (nvdimm_read_bytes(ndns, SZ_4K, btt_sb, sizeof(*btt_sb), 0))
- return -ENXIO;
-
if (nvdimm_namespace_capacity(ndns) < SZ_16M)
return -ENXIO;
- if (!nd_btt_arena_is_valid(nd_btt, btt_sb))
- return -ENODEV;
+ rc = nd_btt_version(nd_btt, ndns, btt_sb);
+ if (rc < 0)
+ return rc;
nd_btt->lbasize = le32_to_cpu(btt_sb->external_lbasize);
nd_btt->uuid = kmemdup(btt_sb->uuid, 16, GFP_KERNEL);
@@ -298,6 +333,7 @@ int nd_btt_probe(struct device *dev, struct nd_namespace_common *ndns)
switch (ndns->claim_class) {
case NVDIMM_CCLASS_NONE:
case NVDIMM_CCLASS_BTT:
+ case NVDIMM_CCLASS_BTT2:
break;
default:
return -ENODEV;
diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c
index de9b1cc..8d23f68 100644
--- a/drivers/nvdimm/claim.c
+++ b/drivers/nvdimm/claim.c
@@ -189,6 +189,7 @@ ssize_t nd_namespace_store(struct device *dev,
case NVDIMM_CCLASS_NONE:
break;
case NVDIMM_CCLASS_BTT:
+ case NVDIMM_CCLASS_BTT2:
if (!is_nd_btt(dev)) {
len = -EBUSY;
goto out_attach;
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index 235f208..922b687 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -21,6 +21,7 @@
#include "nd.h"
static guid_t nvdimm_btt_guid;
+static guid_t nvdimm_btt2_guid;
static guid_t nvdimm_pfn_guid;
static guid_t nvdimm_dax_guid;
@@ -578,6 +579,8 @@ enum nvdimm_claim_class to_nvdimm_cclass(guid_t *guid)
{
if (guid_equal(guid, &nvdimm_btt_guid))
return NVDIMM_CCLASS_BTT;
+ else if (guid_equal(guid, &nvdimm_btt2_guid))
+ return NVDIMM_CCLASS_BTT2;
else if (guid_equal(guid, &nvdimm_pfn_guid))
return NVDIMM_CCLASS_PFN;
else if (guid_equal(guid, &nvdimm_dax_guid))
@@ -593,6 +596,8 @@ static const guid_t *to_abstraction_guid(enum nvdimm_claim_class claim_class,
{
if (claim_class == NVDIMM_CCLASS_BTT)
return &nvdimm_btt_guid;
+ else if (claim_class == NVDIMM_CCLASS_BTT2)
+ return &nvdimm_btt2_guid;
else if (claim_class == NVDIMM_CCLASS_PFN)
return &nvdimm_pfn_guid;
else if (claim_class == NVDIMM_CCLASS_DAX)
@@ -1158,6 +1163,7 @@ int nd_blk_namespace_label_update(struct nd_region *nd_region,
int __init nd_label_init(void)
{
WARN_ON(guid_parse(NVDIMM_BTT_GUID, &nvdimm_btt_guid));
+ WARN_ON(guid_parse(NVDIMM_BTT2_GUID, &nvdimm_btt2_guid));
WARN_ON(guid_parse(NVDIMM_PFN_GUID, &nvdimm_pfn_guid));
WARN_ON(guid_parse(NVDIMM_DAX_GUID, &nvdimm_dax_guid));
diff --git a/drivers/nvdimm/label.h b/drivers/nvdimm/label.h
index 7c8e2cc..1ebf4d3 100644
--- a/drivers/nvdimm/label.h
+++ b/drivers/nvdimm/label.h
@@ -113,6 +113,7 @@ struct nd_namespace_label {
};
#define NVDIMM_BTT_GUID "8aed63a2-29a2-4c66-8b12-f05d15d3922a"
+#define NVDIMM_BTT2_GUID "18633bfc-1735-4217-8ac9-17239282d3f8"
#define NVDIMM_PFN_GUID "266400ba-fb9f-4677-bcb0-968f11d0d225"
#define NVDIMM_DAX_GUID "97a86d9c-3cdd-4eda-986f-5068b4f80088"
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index f05d9b0..c96e313 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1411,6 +1411,58 @@ static ssize_t dpa_extents_show(struct device *dev,
}
static DEVICE_ATTR_RO(dpa_extents);
+static int btt_claim_class(struct device *dev)
+{
+ struct nd_region *nd_region = to_nd_region(dev->parent);
+ int i, loop_bitmask = 0;
+
+ for (i = 0; i < nd_region->ndr_mappings; i++) {
+ struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+ struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
+ struct nd_namespace_index *nsindex;
+
+ nsindex = to_namespace_index(ndd, ndd->ns_current);
+ if (nsindex == NULL)
+ loop_bitmask |= 1;
+ else {
+ /* check whether existing labels are v1.1 or v1.2 */
+ if (__le16_to_cpu(nsindex->major) == 1
+ && __le16_to_cpu(nsindex->minor) == 1)
+ loop_bitmask |= 2;
+ else
+ loop_bitmask |= 4;
+ }
+ }
+ /*
+ * If nsindex is null loop_bitmask's bit 0 will be set, and if an index
+ * block is found, a v1.1 label for any mapping will set bit 1, and a
+ * v1.2 label will set bit 2.
+ *
+ * At the end of the loop, at most one of the three bits must be set.
+ * If multiple bits were set, it means the different mappings disagree
+ * about their labels, and this must be cleaned up first.
+ *
+ * If all the label index blocks are found to agree, nsindex of NULL
+ * implies labels haven't been initialized yet, and when they will,
+ * they will be of the 1.2 format, so we can assume BTT2.0
+ *
+ * If 1.1 labels are found, we enforce BTT1.1, and if 1.2 labels are
+ * found, we enforce BTT2.0
+ *
+ * If the loop was never entered, default to BTT1.1 (legacy namespaces)
+ */
+ switch (loop_bitmask) {
+ case 0:
+ case 2:
+ return NVDIMM_CCLASS_BTT;
+ case 1:
+ case 4:
+ return NVDIMM_CCLASS_BTT2;
+ default:
+ return -ENXIO;
+ }
+}
+
static ssize_t holder_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1433,7 +1485,7 @@ static ssize_t __holder_class_store(struct device *dev, const char *buf)
return -EBUSY;
if (strcmp(buf, "btt") == 0 || strcmp(buf, "btt\n") == 0)
- ndns->claim_class = NVDIMM_CCLASS_BTT;
+ ndns->claim_class = btt_claim_class(dev);
else if (strcmp(buf, "pfn") == 0 || strcmp(buf, "pfn\n") == 0)
ndns->claim_class = NVDIMM_CCLASS_PFN;
else if (strcmp(buf, "dax") == 0 || strcmp(buf, "dax\n") == 0)
@@ -1443,6 +1495,10 @@ static ssize_t __holder_class_store(struct device *dev, const char *buf)
else
return -EINVAL;
+ /* btt_claim_class() could've returned an error */
+ if (ndns->claim_class < 0)
+ return ndns->claim_class;
+
return 0;
}
@@ -1474,7 +1530,8 @@ static ssize_t holder_class_show(struct device *dev,
device_lock(dev);
if (ndns->claim_class == NVDIMM_CCLASS_NONE)
rc = sprintf(buf, "\n");
- else if (ndns->claim_class == NVDIMM_CCLASS_BTT)
+ else if ((ndns->claim_class == NVDIMM_CCLASS_BTT) ||
+ (ndns->claim_class == NVDIMM_CCLASS_BTT2))
rc = sprintf(buf, "btt\n");
else if (ndns->claim_class == NVDIMM_CCLASS_PFN)
rc = sprintf(buf, "pfn\n");
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 8cabd83..1496ef9 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -194,6 +194,9 @@ struct nd_btt {
u64 size;
u8 *uuid;
int id;
+ int initial_offset;
+ u16 version_major;
+ u16 version_minor;
};
enum nd_pfn_mode {
diff --git a/include/linux/nd.h b/include/linux/nd.h
index 96069c5..5dc6b69 100644
--- a/include/linux/nd.h
+++ b/include/linux/nd.h
@@ -24,6 +24,7 @@ enum nvdimm_event {
enum nvdimm_claim_class {
NVDIMM_CCLASS_NONE,
NVDIMM_CCLASS_BTT,
+ NVDIMM_CCLASS_BTT2,
NVDIMM_CCLASS_PFN,
NVDIMM_CCLASS_DAX,
NVDIMM_CCLASS_UNKNOWN,
--
2.9.3
3 years, 6 months
[PATCH v4] libnvdimm, btt: BTT updates for UEFI 2.7 format
by Vishal Verma
The UEFI 2.7 specification defines an updated BTT metadata format,
bumping the revision to 2.0. Add support for the new format, while
retaining compatibility for the old 1.1 format.
Cc: Toshi Kani <toshi.kani(a)hpe.com>
Cc: Linda Knippers <linda.knippers(a)hpe.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
v4:
- Fix up dereferencing of nd_region->mappings (Dan)
- Check all the mappings for label consistency (Dan)
- Refactor figuring out the BTT claim class into its own helper (Dan)
v3:
- Add athe actual BTT2 guid from the UEFI spec, and plumb a new
claim class for it (Dan)
v2:
- Don't enforce new BTTs being v2, base that decision on the holder class (Dan)
- Refactor nd_btt_version slightly, and get rid of the version enum.
drivers/nvdimm/btt.c | 28 ++++++++++++++------
drivers/nvdimm/btt.h | 2 ++
drivers/nvdimm/btt_devs.c | 46 +++++++++++++++++++++++++++++----
drivers/nvdimm/claim.c | 1 +
drivers/nvdimm/label.c | 6 +++++
drivers/nvdimm/label.h | 1 +
drivers/nvdimm/namespace_devs.c | 57 +++++++++++++++++++++++++++++++++++++++--
drivers/nvdimm/nd.h | 3 +++
include/linux/nd.h | 1 +
9 files changed, 130 insertions(+), 15 deletions(-)
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 983718b..7ca11df 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -37,8 +37,8 @@ static int arena_read_bytes(struct arena_info *arena, resource_size_t offset,
struct nd_btt *nd_btt = arena->nd_btt;
struct nd_namespace_common *ndns = nd_btt->ndns;
- /* arena offsets are 4K from the base of the device */
- offset += SZ_4K;
+ /* arena offsets may be shifted from the base of the device */
+ offset += arena->nd_btt->initial_offset;
return nvdimm_read_bytes(ndns, offset, buf, n, flags);
}
@@ -48,8 +48,8 @@ static int arena_write_bytes(struct arena_info *arena, resource_size_t offset,
struct nd_btt *nd_btt = arena->nd_btt;
struct nd_namespace_common *ndns = nd_btt->ndns;
- /* arena offsets are 4K from the base of the device */
- offset += SZ_4K;
+ /* arena offsets may be shifted from the base of the device */
+ offset += arena->nd_btt->initial_offset;
return nvdimm_write_bytes(ndns, offset, buf, n, flags);
}
@@ -576,8 +576,8 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size,
arena->internal_lbasize = roundup(arena->external_lbasize,
INT_LBASIZE_ALIGNMENT);
arena->nfree = BTT_DEFAULT_NFREE;
- arena->version_major = 1;
- arena->version_minor = 1;
+ arena->version_major = btt->nd_btt->version_major;
+ arena->version_minor = btt->nd_btt->version_minor;
if (available % BTT_PG_SIZE)
available -= (available % BTT_PG_SIZE);
@@ -1425,6 +1425,7 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns)
{
struct nd_btt *nd_btt = to_nd_btt(ndns->claim);
struct nd_region *nd_region;
+ struct btt_sb *btt_sb;
struct btt *btt;
size_t rawsize;
@@ -1433,10 +1434,21 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns)
return -ENODEV;
}
- rawsize = nvdimm_namespace_capacity(ndns) - SZ_4K;
+ btt_sb = devm_kzalloc(&nd_btt->dev, sizeof(*btt_sb), GFP_KERNEL);
+
+ /*
+ * If this returns < 0, that is ok as it just means there wasn't
+ * an existing BTT, and we're creating a new one. We still need to
+ * call this as we need the version dependent fields in nd_btt to be
+ * set correctly based on the holder class
+ */
+ nd_btt_version(nd_btt, ndns, btt_sb);
+
+ rawsize = nvdimm_namespace_capacity(ndns) - nd_btt->initial_offset;
if (rawsize < ARENA_MIN_SIZE) {
dev_dbg(&nd_btt->dev, "%s must be at least %ld bytes\n",
- dev_name(&ndns->dev), ARENA_MIN_SIZE + SZ_4K);
+ dev_name(&ndns->dev),
+ ARENA_MIN_SIZE + nd_btt->initial_offset);
return -ENXIO;
}
nd_region = to_nd_region(nd_btt->dev.parent);
diff --git a/drivers/nvdimm/btt.h b/drivers/nvdimm/btt.h
index b2f8651..888e862 100644
--- a/drivers/nvdimm/btt.h
+++ b/drivers/nvdimm/btt.h
@@ -184,5 +184,7 @@ struct btt {
};
bool nd_btt_arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super);
+int nd_btt_version(struct nd_btt *nd_btt, struct nd_namespace_common *ndns,
+ struct btt_sb *btt_sb);
#endif
diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c
index 31d875a..3e359d2 100644
--- a/drivers/nvdimm/btt_devs.c
+++ b/drivers/nvdimm/btt_devs.c
@@ -260,20 +260,55 @@ bool nd_btt_arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super)
}
EXPORT_SYMBOL(nd_btt_arena_is_valid);
+int nd_btt_version(struct nd_btt *nd_btt, struct nd_namespace_common *ndns,
+ struct btt_sb *btt_sb)
+{
+ if (ndns->claim_class == NVDIMM_CCLASS_BTT2) {
+ /* Probe/setup for BTT v2.0 */
+ nd_btt->initial_offset = 0;
+ nd_btt->version_major = 2;
+ nd_btt->version_minor = 0;
+ if (nvdimm_read_bytes(ndns, 0, btt_sb, sizeof(*btt_sb), 0))
+ return -ENXIO;
+ if (!nd_btt_arena_is_valid(nd_btt, btt_sb))
+ return -ENODEV;
+ if ((le16_to_cpu(btt_sb->version_major) != 2) ||
+ (le16_to_cpu(btt_sb->version_minor) != 0))
+ return -ENODEV;
+ } else {
+ /*
+ * Probe/setup for BTT v1.1 (NVDIMM_CCLASS_NONE or
+ * NVDIMM_CCLASS_BTT)
+ */
+ nd_btt->initial_offset = SZ_4K;
+ nd_btt->version_major = 1;
+ nd_btt->version_minor = 1;
+ if (nvdimm_read_bytes(ndns, SZ_4K, btt_sb, sizeof(*btt_sb), 0))
+ return -ENXIO;
+ if (!nd_btt_arena_is_valid(nd_btt, btt_sb))
+ return -ENODEV;
+ if ((le16_to_cpu(btt_sb->version_major) != 1) ||
+ (le16_to_cpu(btt_sb->version_minor) != 1))
+ return -ENODEV;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(nd_btt_version);
+
static int __nd_btt_probe(struct nd_btt *nd_btt,
struct nd_namespace_common *ndns, struct btt_sb *btt_sb)
{
+ int rc;
+
if (!btt_sb || !ndns || !nd_btt)
return -ENODEV;
- if (nvdimm_read_bytes(ndns, SZ_4K, btt_sb, sizeof(*btt_sb), 0))
- return -ENXIO;
-
if (nvdimm_namespace_capacity(ndns) < SZ_16M)
return -ENXIO;
- if (!nd_btt_arena_is_valid(nd_btt, btt_sb))
- return -ENODEV;
+ rc = nd_btt_version(nd_btt, ndns, btt_sb);
+ if (rc < 0)
+ return rc;
nd_btt->lbasize = le32_to_cpu(btt_sb->external_lbasize);
nd_btt->uuid = kmemdup(btt_sb->uuid, 16, GFP_KERNEL);
@@ -298,6 +333,7 @@ int nd_btt_probe(struct device *dev, struct nd_namespace_common *ndns)
switch (ndns->claim_class) {
case NVDIMM_CCLASS_NONE:
case NVDIMM_CCLASS_BTT:
+ case NVDIMM_CCLASS_BTT2:
break;
default:
return -ENODEV;
diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c
index de9b1cc..8d23f68 100644
--- a/drivers/nvdimm/claim.c
+++ b/drivers/nvdimm/claim.c
@@ -189,6 +189,7 @@ ssize_t nd_namespace_store(struct device *dev,
case NVDIMM_CCLASS_NONE:
break;
case NVDIMM_CCLASS_BTT:
+ case NVDIMM_CCLASS_BTT2:
if (!is_nd_btt(dev)) {
len = -EBUSY;
goto out_attach;
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index 235f208..922b687 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -21,6 +21,7 @@
#include "nd.h"
static guid_t nvdimm_btt_guid;
+static guid_t nvdimm_btt2_guid;
static guid_t nvdimm_pfn_guid;
static guid_t nvdimm_dax_guid;
@@ -578,6 +579,8 @@ enum nvdimm_claim_class to_nvdimm_cclass(guid_t *guid)
{
if (guid_equal(guid, &nvdimm_btt_guid))
return NVDIMM_CCLASS_BTT;
+ else if (guid_equal(guid, &nvdimm_btt2_guid))
+ return NVDIMM_CCLASS_BTT2;
else if (guid_equal(guid, &nvdimm_pfn_guid))
return NVDIMM_CCLASS_PFN;
else if (guid_equal(guid, &nvdimm_dax_guid))
@@ -593,6 +596,8 @@ static const guid_t *to_abstraction_guid(enum nvdimm_claim_class claim_class,
{
if (claim_class == NVDIMM_CCLASS_BTT)
return &nvdimm_btt_guid;
+ else if (claim_class == NVDIMM_CCLASS_BTT2)
+ return &nvdimm_btt2_guid;
else if (claim_class == NVDIMM_CCLASS_PFN)
return &nvdimm_pfn_guid;
else if (claim_class == NVDIMM_CCLASS_DAX)
@@ -1158,6 +1163,7 @@ int nd_blk_namespace_label_update(struct nd_region *nd_region,
int __init nd_label_init(void)
{
WARN_ON(guid_parse(NVDIMM_BTT_GUID, &nvdimm_btt_guid));
+ WARN_ON(guid_parse(NVDIMM_BTT2_GUID, &nvdimm_btt2_guid));
WARN_ON(guid_parse(NVDIMM_PFN_GUID, &nvdimm_pfn_guid));
WARN_ON(guid_parse(NVDIMM_DAX_GUID, &nvdimm_dax_guid));
diff --git a/drivers/nvdimm/label.h b/drivers/nvdimm/label.h
index 7c8e2cc..1ebf4d3 100644
--- a/drivers/nvdimm/label.h
+++ b/drivers/nvdimm/label.h
@@ -113,6 +113,7 @@ struct nd_namespace_label {
};
#define NVDIMM_BTT_GUID "8aed63a2-29a2-4c66-8b12-f05d15d3922a"
+#define NVDIMM_BTT2_GUID "18633bfc-1735-4217-8ac9-17239282d3f8"
#define NVDIMM_PFN_GUID "266400ba-fb9f-4677-bcb0-968f11d0d225"
#define NVDIMM_DAX_GUID "97a86d9c-3cdd-4eda-986f-5068b4f80088"
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index f05d9b0..09e7e76 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1411,6 +1411,58 @@ static ssize_t dpa_extents_show(struct device *dev,
}
static DEVICE_ATTR_RO(dpa_extents);
+static int btt_claim_class(struct device *dev)
+{
+ struct nd_region *nd_region = to_nd_region(dev->parent);
+ int i, loop_bitmask = 0;
+
+ for (i = 0; i < nd_region->ndr_mappings; i++) {
+ struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+ struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
+ struct nd_namespace_index *nsindex;
+
+ nsindex = to_namespace_index(ndd, ndd->ns_current);
+ if (nsindex == NULL)
+ loop_bitmask |= 1;
+ else {
+ /* check whether existing labels are v1.1 or v1.2 */
+ if (__le16_to_cpu(nsindex->major) == 1
+ && __le16_to_cpu(nsindex->minor) == 1)
+ loop_bitmask |= 2;
+ else
+ loop_bitmask |= 4;
+ }
+ }
+ /*
+ * If nsindex is null loop_bitmask's bit 0 will be set, and if an index
+ * block is found, a v1.1 label for any mapping will set bit 1, and a
+ * v1.2 label will set bit 2.
+ *
+ * At the end of the loop, only one of the three bits must be set.
+ * If multiple bits were set, it means the different mappings disagree
+ * about their labels, and this must be cleaned up first.
+ *
+ * If all the label index blocks are found to agree, nsindex of NULL
+ * implies labels haven't been initialized yet, and when they will,
+ * they will be of the 1.2 format, so we can assume BTT2.0
+ *
+ * If 1.1 labels are found, we enforce BTT1.1, and if 1.2 labels are
+ * found, we enforce BTT2.0
+ *
+ * If the loop was never entered, default to BTT1.1 (legacy namespaces)
+ */
+ switch (loop_bitmask) {
+ case 0:
+ case 2:
+ return NVDIMM_CCLASS_BTT;
+ case 1:
+ case 4:
+ return NVDIMM_CCLASS_BTT2;
+ default:
+ return -ENXIO;
+ }
+}
+
static ssize_t holder_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1433,7 +1485,7 @@ static ssize_t __holder_class_store(struct device *dev, const char *buf)
return -EBUSY;
if (strcmp(buf, "btt") == 0 || strcmp(buf, "btt\n") == 0)
- ndns->claim_class = NVDIMM_CCLASS_BTT;
+ ndns->claim_class = btt_claim_class(dev);
else if (strcmp(buf, "pfn") == 0 || strcmp(buf, "pfn\n") == 0)
ndns->claim_class = NVDIMM_CCLASS_PFN;
else if (strcmp(buf, "dax") == 0 || strcmp(buf, "dax\n") == 0)
@@ -1474,7 +1526,8 @@ static ssize_t holder_class_show(struct device *dev,
device_lock(dev);
if (ndns->claim_class == NVDIMM_CCLASS_NONE)
rc = sprintf(buf, "\n");
- else if (ndns->claim_class == NVDIMM_CCLASS_BTT)
+ else if ((ndns->claim_class == NVDIMM_CCLASS_BTT) ||
+ (ndns->claim_class == NVDIMM_CCLASS_BTT2))
rc = sprintf(buf, "btt\n");
else if (ndns->claim_class == NVDIMM_CCLASS_PFN)
rc = sprintf(buf, "pfn\n");
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 8cabd83..1496ef9 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -194,6 +194,9 @@ struct nd_btt {
u64 size;
u8 *uuid;
int id;
+ int initial_offset;
+ u16 version_major;
+ u16 version_minor;
};
enum nd_pfn_mode {
diff --git a/include/linux/nd.h b/include/linux/nd.h
index 96069c5..5dc6b69 100644
--- a/include/linux/nd.h
+++ b/include/linux/nd.h
@@ -24,6 +24,7 @@ enum nvdimm_event {
enum nvdimm_claim_class {
NVDIMM_CCLASS_NONE,
NVDIMM_CCLASS_BTT,
+ NVDIMM_CCLASS_BTT2,
NVDIMM_CCLASS_PFN,
NVDIMM_CCLASS_DAX,
NVDIMM_CCLASS_UNKNOWN,
--
2.9.3
3 years, 6 months
[4.11-stable PATCH] x86/mm: Fix boot crash caused by incorrect loop count calculation in sync_global_pgds()
by Dan Williams
From: Baoquan He <bhe(a)redhat.com>
commit fc5f9d5f151c9fff21d3d1d2907b888a5aec3ff7 upstream.
Jeff Moyer reported that on his system with two memory regions 0~64G and
1T~1T+192G, and kernel option "memmap=192G!1024G" added, enabling KASLR
will make the system hang intermittently during boot. While adding 'nokaslr'
won't.
The back trace is:
Oops: 0000 [#1] SMP
RIP: memcpy_erms()
[ .... ]
Call Trace:
pmem_rw_page()
bdev_read_page()
do_mpage_readpage()
mpage_readpages()
blkdev_readpages()
__do_page_cache_readahead()
force_page_cache_readahead()
page_cache_sync_readahead()
generic_file_read_iter()
blkdev_read_iter()
__vfs_read()
vfs_read()
SyS_read()
entry_SYSCALL_64_fastpath()
This crash happens because the for loop count calculation in sync_global_pgds()
is not correct. When a mapping area crosses PGD entries, we should
calculate the starting address of region which next PGD covers and assign
it to next for loop count, but not add PGDIR_SIZE directly. The old
code works right only if the mapping area is an exact multiple of PGDIR_SIZE,
otherwize the end region could be skipped so that it can't be synchronized
to all other processes from kernel PGD init_mm.pgd.
In Jeff's system, emulated pmem area [1024G, 1216G) is smaller than
PGDIR_SIZE. While 'nokaslr' works because PAGE_OFFSET is 1T aligned, it
makes this area be mapped inside one PGD entry. With KASLR enabled,
this area could cross two PGD entries, then the next PGD entry won't
be synced to all other processes. That is why we saw empty PGD.
Fix it.
Reported-by: Jeff Moyer <jmoyer(a)redhat.com>
Signed-off-by: Baoquan He <bhe(a)redhat.com>
Cc: Andrew Morton <akpm(a)linux-foundation.org>
Cc: Andy Lutomirski <luto(a)kernel.org>
Cc: Borislav Petkov <bp(a)alien8.de>
Cc: Brian Gerst <brgerst(a)gmail.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Cc: Dave Hansen <dave.hansen(a)linux.intel.com>
Cc: Dave Young <dyoung(a)redhat.com>
Cc: Denys Vlasenko <dvlasenk(a)redhat.com>
Cc: H. Peter Anvin <hpa(a)zytor.com>
Cc: Jinbum Park <jinb.park7(a)gmail.com>
Cc: Josh Poimboeuf <jpoimboe(a)redhat.com>
Cc: Kees Cook <keescook(a)chromium.org>
Cc: Kirill A. Shutemov <kirill.shutemov(a)linux.intel.com>
Cc: Linus Torvalds <torvalds(a)linux-foundation.org>
Cc: Peter Zijlstra <peterz(a)infradead.org>
Cc: Thomas Garnier <thgarnie(a)google.com>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: Yasuaki Ishimatsu <yasu.isimatu(a)gmail.com>
Cc: Yinghai Lu <yinghai(a)kernel.org>
Link: http://lkml.kernel.org/r/1493864747-8506-1-git-send-email-bhe@redhat.com
Signed-off-by: Ingo Molnar <mingo(a)kernel.org>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
arch/x86/mm/init_64.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 15173d37f399..e1e3f7b4bdb0 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -94,10 +94,10 @@ __setup("noexec32=", nonx32_setup);
*/
void sync_global_pgds(unsigned long start, unsigned long end)
{
- unsigned long address;
+ unsigned long addr;
- for (address = start; address <= end; address += PGDIR_SIZE) {
- const pgd_t *pgd_ref = pgd_offset_k(address);
+ for (addr = start; addr <= end; addr = ALIGN(addr + 1, PGDIR_SIZE)) {
+ const pgd_t *pgd_ref = pgd_offset_k(addr);
struct page *page;
if (pgd_none(*pgd_ref))
@@ -108,7 +108,7 @@ void sync_global_pgds(unsigned long start, unsigned long end)
pgd_t *pgd;
spinlock_t *pgt_lock;
- pgd = (pgd_t *)page_address(page) + pgd_index(address);
+ pgd = (pgd_t *)page_address(page) + pgd_index(addr);
/* the pgt_lock only for Xen */
pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
spin_lock(pgt_lock);
3 years, 6 months
[4.9-stable PATCH] x86/mm: Fix boot crash caused by incorrect loop count calculation in sync_global_pgds()
by Dan Williams
From: Baoquan He <bhe(a)redhat.com>
commit fc5f9d5f151c9fff21d3d1d2907b888a5aec3ff7 upstream.
Jeff Moyer reported that on his system with two memory regions 0~64G and
1T~1T+192G, and kernel option "memmap=192G!1024G" added, enabling KASLR
will make the system hang intermittently during boot. While adding 'nokaslr'
won't.
The back trace is:
Oops: 0000 [#1] SMP
RIP: memcpy_erms()
[ .... ]
Call Trace:
pmem_rw_page()
bdev_read_page()
do_mpage_readpage()
mpage_readpages()
blkdev_readpages()
__do_page_cache_readahead()
force_page_cache_readahead()
page_cache_sync_readahead()
generic_file_read_iter()
blkdev_read_iter()
__vfs_read()
vfs_read()
SyS_read()
entry_SYSCALL_64_fastpath()
This crash happens because the for loop count calculation in sync_global_pgds()
is not correct. When a mapping area crosses PGD entries, we should
calculate the starting address of region which next PGD covers and assign
it to next for loop count, but not add PGDIR_SIZE directly. The old
code works right only if the mapping area is an exact multiple of PGDIR_SIZE,
otherwize the end region could be skipped so that it can't be synchronized
to all other processes from kernel PGD init_mm.pgd.
In Jeff's system, emulated pmem area [1024G, 1216G) is smaller than
PGDIR_SIZE. While 'nokaslr' works because PAGE_OFFSET is 1T aligned, it
makes this area be mapped inside one PGD entry. With KASLR enabled,
this area could cross two PGD entries, then the next PGD entry won't
be synced to all other processes. That is why we saw empty PGD.
Fix it.
Reported-by: Jeff Moyer <jmoyer(a)redhat.com>
Signed-off-by: Baoquan He <bhe(a)redhat.com>
Cc: Andrew Morton <akpm(a)linux-foundation.org>
Cc: Andy Lutomirski <luto(a)kernel.org>
Cc: Borislav Petkov <bp(a)alien8.de>
Cc: Brian Gerst <brgerst(a)gmail.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Cc: Dave Hansen <dave.hansen(a)linux.intel.com>
Cc: Dave Young <dyoung(a)redhat.com>
Cc: Denys Vlasenko <dvlasenk(a)redhat.com>
Cc: H. Peter Anvin <hpa(a)zytor.com>
Cc: Jinbum Park <jinb.park7(a)gmail.com>
Cc: Josh Poimboeuf <jpoimboe(a)redhat.com>
Cc: Kees Cook <keescook(a)chromium.org>
Cc: Kirill A. Shutemov <kirill.shutemov(a)linux.intel.com>
Cc: Linus Torvalds <torvalds(a)linux-foundation.org>
Cc: Peter Zijlstra <peterz(a)infradead.org>
Cc: Thomas Garnier <thgarnie(a)google.com>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: Yasuaki Ishimatsu <yasu.isimatu(a)gmail.com>
Cc: Yinghai Lu <yinghai(a)kernel.org>
Link: http://lkml.kernel.org/r/1493864747-8506-1-git-send-email-bhe@redhat.com
Signed-off-by: Ingo Molnar <mingo(a)kernel.org>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
arch/x86/mm/init_64.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 14b9dd71d9e8..9a324fc8bed8 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -94,10 +94,10 @@ __setup("noexec32=", nonx32_setup);
*/
void sync_global_pgds(unsigned long start, unsigned long end, int removed)
{
- unsigned long address;
+ unsigned long addr;
- for (address = start; address <= end; address += PGDIR_SIZE) {
- const pgd_t *pgd_ref = pgd_offset_k(address);
+ for (addr = start; addr <= end; addr = ALIGN(addr + 1, PGDIR_SIZE)) {
+ const pgd_t *pgd_ref = pgd_offset_k(addr);
struct page *page;
/*
@@ -113,7 +113,7 @@ void sync_global_pgds(unsigned long start, unsigned long end, int removed)
pgd_t *pgd;
spinlock_t *pgt_lock;
- pgd = (pgd_t *)page_address(page) + pgd_index(address);
+ pgd = (pgd_t *)page_address(page) + pgd_index(addr);
/* the pgt_lock only for Xen */
pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
spin_lock(pgt_lock);
3 years, 6 months
人力资源必修课,学会个税筹划的技巧及降本提效的方法
by 荆呱
Message-ID: 448041728843
From: =?cg??= <linux-nvdimm(a)lists.01.org>
To: <ppof(a)japbdzcap.com>
3 years, 6 months
如何制定企业战略规划
by 盖甲
Message-ID: 2997810801955
From: =?3jze2hr??= <linux-nvdimm(a)lists.01.org>
To: <qto(a)ua.net>
如何制定企业战略规划实战
时间地点:2017年7月7-8日 深圳 福田区深圳华霆酒店
培训费用: 5800元/人
课程对象: 本课程适用于企业家、董事会成员、总经理、副总经理、总监、部门经理等中高层管理者和战略管理专业人员。
联系电话: 0755-61288035 010-51661863 021-31261580
咨询报名QQ: 6983436 报名邮箱: px.zhao(a)hotmail.com (报名请回复尾末报名表)
【课程收益】
本课程通过战略理论、方法及案例的分析与讲解,拓展战略视野,提升战略思维,帮助管理者全面认识战略基本框架,掌握战略分析方法和战略规划技巧,提升企业的战略规划能力、战略理解能力和战略执行能力,从而提升企业整体战略管理能力,促进企业快速、健康、持续发展。
【课程大纲】
第一部分 战略概述
【情景案例1-1】
1、竞争战略、蓝海战略与发展战略
2、战略是什么?
3、战略的构成
(1)愿景
(2)战略目标
(3)业务战略
(4)职能战略
4、为什么要制定战略?
5、怎样制定战略?
6、谁来制定战略?
【战略案例1-2】
【战略案例1-3】
【战略案例1-4】
第二部分 外部环境分析
【情景案例2-1】
1、外部环境分析的主要框架
2、如何进行宏观环境分析?
(1)经济因素
(2)政治/法律因素
(3)人口因素
(4)社会/文化因素
(5)地理因素
(6)科技因素
3、如何进行行业环境分析?
(1)市场需求分析与趋势预测(各种方法介绍)
(2)市场供给分析与趋势预测(各种方法介绍)
(3)市场供给与需求比较及未来趋势预测
4、产业、区域、客户、产品分析
(1)各子产业市场发展趋势预测(各种方法介绍)
(2)各区域市场发展趋势预测(各种方法介绍)
(3)各类客户市场发展趋势预测(各种方法介绍)
(4)各类产品市场发展趋势预测(各种方法介绍)
5、如何进行竞争环境分析?
(1)整体竞争环境分析
(2)各竞争对手类型分析
(3)重点竞争对手分析
(4)行业标杆研究及学习
(2)顾客分析
6、如何分析客户或消费者?
(1)客户类型分析
(2)目标客户发展趋势分析
(3)目标客户核心需求及消费行业研究
7、产业价值链分析
(1)产业价值链与企业价值链
(2)产业价值链分析
【战略案例2-2】
【战略案例2-3】
【战略案例2-4】
第三部分 企业内部分析
【情景案例3-1】
1、内部分析的框架
2、如何判断企业的发展阶段?
(1)企业生命周期分析
(2)产品生命周期分析
(3)战略发展阶段分析
3、如何分析企业总体发展状况?
(1)财务分析主要方法
(2)财务分析主要指标
(3)企业整体发展状况分析
4、如何分析企业各业务发展状况?
(1)产业发展状况分析
(2)区域发展状况分析
(3)客户发展状况分析
(4)产品发展状况分析
5、如何分析企业能力?
(1)资源与能力分析
(2)整体运营能力分析
(3)成本控制能力分析
(4)核心竞争力分析(核心竞争力与核心发展力区别与联系)
6、如何将内外部分析相结合——SW0T分析
【战略案例3-2】
【战略案例3-3】
【战略案例3-4】
第四部分 战略规划
【情景案例4-1】
1、如何系统思考企业发展?
(1)重新回顾发展战略构架
(2)发展战略框架思考顺序
(3)发展战略制定整体框架
2、怎样确定企业愿景?
(1)愿景是什么?
(2)愿景是企业发展的指南针
(3)愿景创建程序
(4)企业愿景创建需注意的方面
3、怎样制定战略目标?
(1)战略目标主要指标
(2)战略目标的类型
(3)战略目标的选择
(4)战略目标制定步骤
3、怎样制定业务战略?
(1)产业战略
(2)区域战略
(3)客户战略
(4)产品战略
4、怎样制定职能战略?
(1)职能战略与核心发展能力
(2)市场营销战略
(3)技术研发战略
(4)生产制造战略
(5)财务投资战略
(6)人力资源战略
【战略案例4-2】
【战略案例4-3】
【战略案例4-4】
第五部分 战略规划案例演示
战略规划案例演示(一)
战略规划案例演示(二)
战略规划案例演示(三)
【学员评语】
“唐东方老师讲述的发展战略框架非常好,在愿景与目标指引下,通过产业、区域、客户和产品等四个方面发展点的思考,帮企业清晰地找到了发展之匙。”
——福田戴姆勒总裁兼首席执行官周亮
“唐老师讲得非常好,非常实用,启发很大,期待唐老师进一步指导公司战略实践。”
——红豆集团总裁周海江
“听了唐老师几次战略课程,感觉受益非浅,唐老师关于发展战略的基本框架,为企业解决发展问题提供了思路和方法。”
——豪森瑞德董事长董德熙
“非常喜欢唐老师的战略课程,唐老师的发展战略思想与框架对青岛双瑞的发展启发很大。”
——青岛双瑞总经理付洪田
“从发展方向、战略速度与质量、发展点、发展能力来考虑企业发展,使企业发展得到了实实在在的保证,非常喜欢唐老师的课程,深入浅出,非常生动。”
——明志科技董事长邱壑
“唐东方老师在两天的培训课时中以极度热情与敬业的职业精神给我们带来了一次精彩的培训讲座,其条理清晰、案例详实、重点突出、通俗易懂的讲授让参训人员获益匪浅。唐老师这两天对战略制定理论、方法与技巧的讲解,为众多企业制定战略提供了借鉴,开启了企业发展之门。”
——三友集团董事长宋朝阳
“唐东方老师的战略课程让人更加深刻地理解战略的基本框架,以及作出战略决策的理论、方法与技巧。这对于正在学习和发展战略思维的中国企业家和职业经理人来说,无疑是绝好的培训,值得听听!”
——星网锐捷总经理刘中东
“因临时受国务院副总理马凯接见,只听了唐老师的一天课程,但发展战略框架给我影响深刻,我相信他将对企业现有的发展思路与模式带来巨大的变化。”
——卫士通总经理杨新
“听了唐老师的课,受益非浅。课程有两大特色:一是内容系统性强、逻辑严密、实战力强,理论与方法论均能落地;二是案例丰富、启发性大,课程真的是物有超值!真有幸听了唐老师课程,在工作中一定好好运用。”
——中盟科技总裁助理周代进
“唐老师课程有几个突出特点:1、课程逻辑清楚、重点突出:整个过程始终围绕发展战略框架,强调公司发展;2、案例丰富:课程通过大量真实案例讲解,清楚明了,练习也通过真实案例,印象深刻;3、语言平实,耐心解惑。非常喜欢唐老师。”
——水井坊董事会办公室主任陆莉女士
“听完唐老师的课程,突出的感受是课程结构完整,逻辑清晰,具有将战略转化为战略执行的全面理论框架,并且配套丰富的课堂练习,可以很好地将知识转化成能力,实操性强。”
——中集集团战略绩效经理蔡芳
“通过两天的学习,让我熟练掌握发展战略框架,熟悉如何去分析内外部环境,如何去制定年度经营计划。本次培训唐老师帮我们把知识结构化,并梳理出精髓内容。在未来的工作中,我会运用唐老师的思路,指导自我团队的管理工作,把思路运用到公司明年经营计划的制定。”
——劲胜股份企业管理部经理肖卫凡
【讲师简介】
唐东方,著名战略专家,发展战略理论创建人,东方战略研究中心研究员。唐老师突出的特点是实战性,拥有十余年一百多家企业战略咨询经验,著有“发展战略四部曲”:《战略选择》《战略规划三部曲》《战略绩效管理》《战略对决》,系统阐述了发展战略思想、理念与方法论,开创了发展战略理论,与波特“竞争战略三部曲”相媲美,被业界誉为“中国波特”。
唐东方为企业战略理论作出了重大贡献,其创建的发展战略理论,是目前中国最实用、最受欢迎的战略理论体系。发展战略理论是其与其咨询团队十余年管理实践经验、管理咨询经验和战略理论方法研究相结合的结晶。唐东方及其团队已经成功地运用发展战略理论体系帮助百余家企业取得了显著的业绩,实现了快速、健康、持续的发展。目前发展战略理论体系已经成为中国最受欢迎、最实用的战略方法论体系,被广大企业接纳与运用。唐东方及其团队已经成功地帮助百余家企业制定了企业战略,并取得了显著的业绩,实现了快速、健康、持续的发展。
唐东方主要代表著作有“发展战略四部曲”:《战略选择》《战略规划三部曲》《战略绩效管理》《战略对决》。这四本书是系统地阐述了发展战略理论与思想,全面介绍了战略的框架、制定及实施过程,并通过多个成功企业的发展战略来进行演绎。这四本书为企业战略学作出了突出的贡献,被业界称为“发展战略四部曲”,可与著名战略学家迈克尔·波特的“竞争战略三部曲”相媲美。这几本书也长期列当当网、卓越网战略类畅销书前列。
报 名 回 执
参加课题:2017年7月7-8日 深圳 如何制定企业战略规划实战
参会单位名称:___________________________________ Email:______________________
如发票抬头与本回执单位名称不同的。请注明:___________________________________
联系人:_______________ 电话:_____________________ 传真:_____________________
参加学员:_______________职务:_______________手机:_______________Email:____________
参加学员:_______________职务:_______________ 手机:_______________Email:____________
参加学员:_______________职务:_______________手机:_______________Email:____________
付款方式:□现金 □转帐 人数:______人 参会费用:共计:______元
3 years, 6 months