抽样检验与品质保证
by 惠傲
Message-ID: 1817327949768
From: =?8sexgt??= <linux-nvdimm(a)lists.01.org>
To: <lnxs(a)shbcidjvv.com>
抽样检验与品质保证
培训目标:
² 了解抽样的基本概念;
² 通过OC曲线了解统计抽样中的风险,学会正确地选用计量值与计数值各种不同的抽样计划,并合理应用;
² 了解抽样检验,全数检验的科学性,合理、经济的实施检验,从而有效地帮助减低质量成本,减少人力资源的浪费,提高产品质量抽检的有效性;
² 掌握不同的情况下如何设计和选择不同的抽样方案,并能制订适于公司实际要求的抽样计划。
培训方法:
v 实际案例讲解
通过企业中质量检验方案的实例案例讲解,来说明抽样检验的原理、运用步骤、注意事项。
v 小组练习
通过小组练习来提高对培训内容的了解,掌握统计抽样检验的具体要求以及在质量检验策划中的应用。
培训评估:
培训评估考虑出勤率及课堂讨论的参与积极性,并包括以下方面:
² 课堂上积极有意义的提问
² 知识的探讨和分享
² 积极参与小组练习
评分练习:
通过评分练习来了解培训的实际效果,形式为统计抽样检验的理解应用练习。
² 最终评估
² 通过最终评估了解培训的整体效果,并策划改进方案
课程大纲:
第1章 抽样检验概述
1.1 “验证”、“检验”与“试验”的概念
1.2 检验的分类与检验方式的选择
1.3 抽样检验
1.4 统计抽样国家标准
1.5 抽样检验标准的选择
第2章 统计抽样检验基本事项的说明
2.1 单位产品
2.2 不合格与不合格品
2.3 批的组成、提交与批的质量表示方法
2.4 样本的选择与样本质量的表示方法
2.5 检查后批的处理
2.6 致命不合格的处理
2.7 抽检特性曲线——OC曲线
第3章 计数型抽样检验标准使用说明(以GB/T2828.1/ ISO2859-1为例)
3.1 GB/T2828.1/ISO2859-1的发展历程
3.2 GB/T2828.1/ISO2859-1的适用范围
3.3 GB/T2828.1/ISO2859-1的设计原则
3.4 GB/T2828.1/ISO2859-1抽样检验要素
3.5 抽样方案
3.6 抽样计划
第4章 抽样计划的设计方法和步骤
4.1 企业抽样计划/方案设计的说明
4.2 企业抽样计划/方案设计实例
4.3 关于抽样计划/方案的进一步信息
1) 平均样本量
2) 平均出厂质量
3) 平均出厂质量上限
第5章 常见的其他计数型抽样标准的介绍
5.1 ANSI/ASQ Z1.4/MIL-STD-105E的发展历史
5.2 ANSI/ASQ Z1.4与GB/T2828.1/ISO2859-1的比较及应用
5.3 ANSI/ASQ Z1.4与MIL-STD-105E的比较及应用
5.4 汽车行业Ac=0的抽样方案,以MIL-STD-1916美国防部抽样检验标准为例
第6章 计量型抽样检验标准的应用(以MIL-STD-414为例)
6.1 计量型抽样检验标准的设计原理简介
6.2 计量型抽样检验标准与计数型抽样检验标准的比较及应用
6.3 MIL-STD-414、ANSI/ASQ414、GB/T6378-2002)抽样检验标准使用方法及案例
学员背景要求:
具备基本的电脑操作,基本质量管理体系、质量检验策划知识和过程控制理论,以及基本的产品生产过程知识。
讲师介绍:徐老师
硕士,六西格玛黑带,精益生产顾问。徐老师是企业管理专家,实战经验丰富。擅长6西格玛和精益生产的具体应用,精通AIAG五大工具、VDA在汽车行业的应用,对DOE、质量成本应用推广有深入的研究,对现场防错、6S与目视化、精益改善具有丰富的实战经验,多次带领企业团队开展减少浪费、QCC实战、目视化改善和现场布局改善。在其多年的职业生涯中,曾先后在国内外一些著名的汽车、机械制造、电子科技等大型企业从事管理和咨询工作,担任过质量经理、生产经理,熟悉国际知名OEM的特殊要求 ( 诸如:VW,Ford,BWM,GM...),辅导多家企业顺利取得大众A级供应商资格, 被聘为多家企业的高级管理顾问。
国际管理标准被引入国内后, 徐老师是最早开展体系咨询工作的一批咨询顾问,也是最早由体系咨询成功转化为专案管理咨询和管理培训的咨询顾问。为一百多家企业进行过管理标准的培训和现场改善项目辅导,对如何将标准和各种管理手法、管理工具有效地运用于企业实践,积累了相当丰富的实际经验。徐老师曾代表多家国内外权威认证机构和咨询机构开展过近百场各种类型的公开班培训,为数十家不同企业开展了项目辅导式专案培训和现场改善专项辅导。
徐老师讲课,一贯采用企业内部语言,通俗易懂,并采用互动式授课模式,能够举出大量的实际案例,引导学员全程参与课程的问题讨论,讨论过程中也可结合企业自身产品、工艺的特点、疑点案例进行分析及现场演练,使学员能够加深对课程的理解,现学现用,确保能够熟练应用到以后的工作中;通过案例和具体情景演练,使培训过程更加生动、幽默、活泼、充满趣味性和知识性。
服务客户有:
上汽集团、德尔福、普利司通、东风汽车、宝马格(中国)、王子纸业、凸版印刷、日立、神钢、依工ITW、江森座椅、博世、兄弟中国、长电科技、广电电子、中粮集团、紫江企业、航天科技、威士伯、杜邦、扬子江、中国石油、梅山钢铁、天马、利富高、天纳克、椿本汽车发动机、矢崎、展讯通信等。
授课形式:知识讲解、案例分析讨论、角色演练、小组讨论、互动交流、游戏感悟、头脑风暴、强调学员参与。
培训时间/地点:2017年7月4-5日(星期二~星期三)/上海
报名详情:
收费标准:¥2800/人(含授课费,合影费、资料费,茶点、会务费,两天午餐费)
联系电话: 021-31261580 赵先生
咨询报名QQ: 6983436 报名邮箱: px.zhao(a)hotmail.com (报名请回复报名表)
--------------------------------------------------------------------------------------------------------------------------
报 名 回 执(请务必于开课前7天回复)
姓名性别部门/职位课程名称TelFaxEmail/手机
培训负责人:公司名称:公司地址:
★缴费方式: o 支票 o 现场缴费 o 汇款(汇款后请将汇款单据传真至本公司)
5 years, 1 month
[PATCH v3] 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>
---
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 | 38 ++++++++++++++++++++++++++++++----
drivers/nvdimm/nd.h | 3 +++
include/linux/nd.h | 1 +
9 files changed, 109 insertions(+), 17 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..a11c189 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1427,14 +1427,43 @@ static DEVICE_ATTR_RO(holder);
static ssize_t __holder_class_store(struct device *dev, const char *buf)
{
+ struct nd_region *nd_region = to_nd_region(dev->parent);
+ struct nd_mapping *nd_mapping = &nd_region->mapping[0];
struct nd_namespace_common *ndns = to_ndns(dev);
+ int use_btt_legacy = 0;
+
+ /* for legacy/label-less namespaces, just use BTT1 */
+ if (nd_mapping != NULL && nd_mapping->nvdimm != NULL) {
+ struct nd_namespace_index *nsindex;
+ struct nvdimm_drvdata *ndd;
+
+ ndd = to_ndd(nd_mapping);
+ nsindex = to_namespace_index(ndd, ndd->ns_current);
+ if (nsindex == NULL) {
+ ;
+ /*
+ * Labels haven't been initialized yet, and when they
+ * will, they will be of the 1.2 format, so we can
+ * assume BTT2.0
+ */
+ } else {
+ /* check if existing labels are v1.1 */
+ if (__le16_to_cpu(nsindex->major) == 1
+ && __le16_to_cpu(nsindex->minor) == 1)
+ use_btt_legacy = 1;
+ }
+ } else
+ use_btt_legacy = 1;
if (dev->driver || ndns->claim)
return -EBUSY;
- if (strcmp(buf, "btt") == 0 || strcmp(buf, "btt\n") == 0)
- ndns->claim_class = NVDIMM_CCLASS_BTT;
- else if (strcmp(buf, "pfn") == 0 || strcmp(buf, "pfn\n") == 0)
+ if (strcmp(buf, "btt") == 0 || strcmp(buf, "btt\n") == 0) {
+ if (use_btt_legacy)
+ ndns->claim_class = NVDIMM_CCLASS_BTT;
+ else
+ ndns->claim_class = NVDIMM_CCLASS_BTT2;
+ } 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)
ndns->claim_class = NVDIMM_CCLASS_DAX;
@@ -1474,7 +1503,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
5 years, 1 month
RE: [PATCH] mm/hwpoison: Clear PRESENT bit for kernel 1:1 mappings of poison pages
by Elliott, Robert (Persistent Memory)
> > > + if (set_memory_np(decoy_addr, 1))
> > > + pr_warn("Could not invalidate pfn=0x%lx from 1:1 map \n",
Another concept to consider is mapping the page as UC rather than
completely unmapping it.
The uncorrectable error scope could be smaller than a page size, like:
* memory ECC width (e.g., 8 bytes)
* cache line size (e.g., 64 bytes)
* block device logical block size (e.g., 512 bytes, for persistent memory)
UC preserves the ability to access adjacent data within the page that
hasn't gone bad, and is particularly useful for persistent memory.
---
Robert Elliott, HPE Persistent Memory
5 years, 1 month
[PATCH 1/4] libndctl: rename parse_lbasize to parse_sizes
by Oliver O'Halloran
We want to re-use this code to parse the list of supported alignments
for dax and PFN devices so rename the function to reflect the more
generic usage.
Signed-off-by: Oliver O'Halloran <oohall(a)gmail.com>
---
ndctl/lib/libndctl.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 4acebc05d6db..aa262f03303e 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -234,12 +234,12 @@ struct ndctl_region {
};
/**
- * struct ndctl_lbasize - lbasize info for btt and blk-namespace devices
+ * struct ndctl_sizes - list of supported sector or alignments
* @select: currently selected sector_size
* @supported: possible sector_size options
* @num: number of entries in @supported
*/
-struct ndctl_lbasize {
+struct ndctl_sizes {
int select;
unsigned int *supported;
int num;
@@ -270,7 +270,7 @@ struct ndctl_namespace {
unsigned long long resource, size;
char *alt_name;
uuid_t uuid;
- struct ndctl_lbasize lbasize;
+ struct ndctl_sizes lbasize;
int numa_node;
};
@@ -291,7 +291,7 @@ struct ndctl_btt {
struct ndctl_region *region;
struct ndctl_namespace *ndns;
struct list_node list;
- struct ndctl_lbasize lbasize;
+ struct ndctl_sizes lbasize;
unsigned long long size;
char *btt_path;
char *btt_buf;
@@ -2855,8 +2855,8 @@ static char *get_block_device(struct ndctl_ctx *ctx, const char *block_path)
return bdev_name;
}
-static int parse_lbasize_supported(struct ndctl_ctx *ctx, const char *devname,
- const char *buf, struct ndctl_lbasize *lba);
+static int parse_sizes(struct ndctl_ctx *ctx, const char *devname,
+ const char *buf, struct ndctl_sizes *lba);
static void *add_namespace(void *parent, int id, const char *ndns_base)
{
@@ -2908,7 +2908,7 @@ static void *add_namespace(void *parent, int id, const char *ndns_base)
sprintf(path, "%s/sector_size", ndns_base);
if (sysfs_read_attr(ctx, path, buf) < 0)
goto err_read;
- if (parse_lbasize_supported(ctx, devname, buf, &ndns->lbasize) < 0)
+ if (parse_sizes(ctx, devname, buf, &ndns->lbasize) < 0)
goto err_read;
/* fall through */
case ND_DEVICE_NAMESPACE_PMEM:
@@ -3738,8 +3738,8 @@ NDCTL_EXPORT int ndctl_namespace_delete(struct ndctl_namespace *ndns)
return 0;
}
-static int parse_lbasize_supported(struct ndctl_ctx *ctx, const char *devname,
- const char *buf, struct ndctl_lbasize *lba)
+static int parse_sizes(struct ndctl_ctx *ctx, const char *devname,
+ const char *buf, struct ndctl_sizes *lba)
{
char *s = strdup(buf), *end, *field;
void *temp;
@@ -3830,7 +3830,7 @@ static void *add_btt(void *parent, int id, const char *btt_base)
sprintf(path, "%s/sector_size", btt_base);
if (sysfs_read_attr(ctx, path, buf) < 0)
goto err_read;
- if (parse_lbasize_supported(ctx, devname, buf, &btt->lbasize) < 0)
+ if (parse_sizes(ctx, devname, buf, &btt->lbasize) < 0)
goto err_read;
sprintf(path, "%s/size", btt_base);
--
2.9.4
5 years, 1 month
[PATCH] ndctl: Add alignment to the namespace JSON output
by Oliver O'Halloran
Automated tooling probably wants to know this and it's helpful output
for command line users for ndctl.
Signed-off-by: Oliver O'Halloran <oohall(a)gmail.com>
---
util/json.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/util/json.c b/util/json.c
index b718d747c285..9e4aa2655514 100644
--- a/util/json.c
+++ b/util/json.c
@@ -443,6 +443,7 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns,
struct ndctl_btt *btt;
struct ndctl_pfn *pfn;
struct ndctl_dax *dax;
+ unsigned long align = 0;
char buf[40];
uuid_t uuid;
@@ -509,6 +510,7 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns,
bdev = ndctl_btt_get_block_device(btt);
} else if (pfn) {
+ align = ndctl_pfn_get_align(pfn);
ndctl_pfn_get_uuid(pfn, uuid);
uuid_unparse(uuid, buf);
jobj = json_object_new_string(buf);
@@ -519,6 +521,7 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns,
} else if (dax) {
struct daxctl_region *dax_region;
+ align = ndctl_dax_get_align(dax);
ndctl_dax_get_uuid(dax, uuid);
uuid_unparse(uuid, buf);
jobj = json_object_new_string(buf);
@@ -553,6 +556,13 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns,
} else
bdev = ndctl_namespace_get_block_device(ndns);
+ if (align) {
+ jobj = json_object_new_int64(align);
+ if (!jobj)
+ goto err;
+ json_object_object_add(jndns, "align", jobj);
+ }
+
if (bdev && bdev[0]) {
jobj = json_object_new_string(bdev);
if (!jobj)
--
2.9.4
5 years, 1 month
[PATCH v2] 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>
---
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/nd.h | 3 +++
4 files changed, 66 insertions(+), 13 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..cd0718e 100644
--- a/drivers/nvdimm/btt_devs.c
+++ b/drivers/nvdimm/btt_devs.c
@@ -260,20 +260,56 @@ 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)
+{
+ /*
+ * At this point, the claim class can only be 'BTT' or 'NONE'. BTT
+ * implies a BTT v2.0 and none implies v1.1
+ */
+ if (ndns->claim_class == NVDIMM_CCLASS_BTT) {
+ /* 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 */
+ 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 btt_ver;
+
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;
+ btt_ver = nd_btt_version(nd_btt, ndns, btt_sb);
+ if (btt_ver < 0)
+ return btt_ver;
nd_btt->lbasize = le32_to_cpu(btt_sb->external_lbasize);
nd_btt->uuid = kmemdup(btt_sb->uuid, 16, GFP_KERNEL);
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 {
--
2.9.3
5 years, 1 month
Product Inquiry
by Julian Smith
Hello,
My name is Ms Julian Smith and i am from Sinara Group Co.
We are glad to know about your company from the web and we are interested in
your products.Please send us your Latest catalog and price list for our
trial order.
Julian Smith,
Purchasing Manager
Sinara Group Co.
7 Krasnogo Znameni Ave.
Vladivostok,690106,Ukraine
5 years, 1 month
[PATCH] 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.
New BTTs will be created using the newest (2.0 as of this writing)
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>
---
drivers/nvdimm/btt.c | 28 ++++++++++++++++++++--------
drivers/nvdimm/btt.h | 7 +++++++
drivers/nvdimm/btt_devs.c | 44 +++++++++++++++++++++++++++++++++++++++-----
drivers/nvdimm/nd.h | 1 +
4 files changed, 67 insertions(+), 13 deletions(-)
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 983718b..629c376 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,10 @@ 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;
+
+ /* New BTTs will always be v2.0 */
+ arena->version_major = 2;
+ arena->version_minor = 0;
if (available % BTT_PG_SIZE)
available -= (available % BTT_PG_SIZE);
@@ -1425,18 +1427,28 @@ 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;
+ int btt_ver;
if (!nd_btt->uuid || !nd_btt->ndns || !nd_btt->lbasize) {
dev_dbg(&nd_btt->dev, "incomplete btt configuration\n");
return -ENODEV;
}
- rawsize = nvdimm_namespace_capacity(ndns) - SZ_4K;
+ btt_sb = devm_kzalloc(&nd_btt->dev, sizeof(*btt_sb), GFP_KERNEL);
+ btt_ver = nd_btt_version(nd_btt, ndns, btt_sb);
+ if (btt_ver < 0) {
+ dev_err(&nd_btt->dev, "%s: set initial_offset = 0\n", __func__);
+ nd_btt->initial_offset = 0;
+ }
+
+ 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..1845df2 100644
--- a/drivers/nvdimm/btt.h
+++ b/drivers/nvdimm/btt.h
@@ -44,6 +44,11 @@ enum btt_init_state {
INIT_READY
};
+enum btt_versions {
+ ND_BTT_1_1 = 1,
+ ND_BTT_2_0
+};
+
struct log_entry {
__le32 lba;
__le32 old_map;
@@ -184,5 +189,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..22e148a 100644
--- a/drivers/nvdimm/btt_devs.c
+++ b/drivers/nvdimm/btt_devs.c
@@ -260,20 +260,54 @@ 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)
+{
+ /*
+ * At this point, the claim class can only be 'BTT' or 'NONE'. BTT
+ * implies a BTT v2.0 and none implies v1.1
+ */
+ if (ndns->claim_class == NVDIMM_CCLASS_BTT) {
+ /* Probe for BTT v2.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)) {
+ nd_btt->initial_offset = 0;
+ return ND_BTT_2_0;
+ }
+ } else {
+ /* Probe for BTT v1.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)) {
+ nd_btt->initial_offset = SZ_4K;
+ return ND_BTT_1_1;
+ }
+ }
+ return -ENXIO;
+}
+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 btt_ver;
+
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;
+ btt_ver = nd_btt_version(nd_btt, ndns, btt_sb);
+ if (btt_ver < 0)
+ return btt_ver;
nd_btt->lbasize = le32_to_cpu(btt_sb->external_lbasize);
nd_btt->uuid = kmemdup(btt_sb->uuid, 16, GFP_KERNEL);
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 8cabd83..474ad8a 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -194,6 +194,7 @@ struct nd_btt {
u64 size;
u8 *uuid;
int id;
+ int initial_offset;
};
enum nd_pfn_mode {
--
2.9.3
5 years, 1 month
[ndctl PATCH] ndctl, check-namespace: fix resource leak
by Dan Williams
Static analysis points out that we leak 'bttc' in namespace_check().
Cc: Vishal Verma <vishal.l.verma(a)intel.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
ndctl/check.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/ndctl/check.c b/ndctl/check.c
index 3775c2ed4a3a..2d913cf5a4c2 100644
--- a/ndctl/check.c
+++ b/ndctl/check.c
@@ -898,7 +898,8 @@ int namespace_check(struct ndctl_namespace *ndns, struct check_opts *opts)
if (sigaction(SIGBUS, &act, 0)) {
err(bttc, "Unable to set sigaction\n");
- return -errno;
+ rc = -errno;
+ goto out_bttc;
}
bttc->opts = opts;
@@ -912,7 +913,7 @@ int namespace_check(struct ndctl_namespace *ndns, struct check_opts *opts)
if (opts->force) {
rc = ndctl_namespace_disable_safe(ndns);
if (rc)
- return rc;
+ goto out_bttc;
disabled_flag = 1;
} else {
err(bttc, "%s: check aborted, namespace online\n",
5 years, 1 month