linux-nvdimm
by zlyxui
销售精英2天强化训练——课程简介
【时间地点】 2016年08月27-28日深圳 09月10-11日北京 09月24-25日上海 10月15-16日深圳 11月05-06日上海 11月19-20日北京 11月26-27日深圳 12月17-18日上海
【参加对象】 总经理、销售总监、区域经理、销售经理、业务代表、销售培训专员等。
【学习费用】 2800元/1人,(2中餐, 税费,专家演讲费,教材费,茶点等);住宿统一安排,费用自理;
【值班手机】 0512-68700653 (0)18015596327
Judge(评价)一个人,一个公司是不是优秀,不要看他是不是Harvard(哈佛大学),是不是Stanford(斯坦福大学).不要judge(评价)里面有多少名牌大学毕业生,而要judge(评价)这帮人干活是不是发疯一样干,看他每天下班是不是笑眯眯回家!
——阿里巴巴公司马云
第一章客户需求分析
思考:
1、面对客户找不到话说,怎么办?二次沟通应该聊些什么?
2、为什么我把所有资料都给客户了,他还说要考虑一下?
3、同一件事,客户不同的人告诉我不一样的要求,听谁的?
4、同一件事,客户同一个人告诉我两次的答案不一样,听哪次的?
5、推荐哪一种产品给客户好?最好的?稍好的?还是够用的?
4、为什么我按客户要求去做,他还是没有选择我们?
5、不同的客户,我应该如何应对?
6、忠诚的客户应该如何培养?
第一节、为什么要对客户需求进行分析?
1、客户初次告诉我们的信息往往是有所保留的;
2、客户想要的产品,不一定就是实际所需要的;
3、客户不缺少产品信息,困惑的是自己如何选择;
4、客户购买决定是比较出来的,没有比较,产品就没有价值;
5、销售人员第一思想是战争思想,情报最重要;
6、未来的送货员,联络员,报价员将被淘汰;
第二节、如何做好客户需求分析?
一、基本要求:
1.无事不登三宝殿,有目的地做好拜访计划;
2.引导客户,首先要控制谈话的方向、节奏、内容;
3.从讲产品的“卖点”转变到讲客户的“买点”
4.好的,不一定是最适合的,最合适的才是最好的;
5.不要把猜测当成事实,“谈”的是什么?“判”是由谁判?
6.讨论:客户说价格太贵,代表哪15种不同的意思?
二、需求分析要点:
1.了解客户的4种期望目标;
2.了解客户采购的5个适当;
3.判断谁是关键人的8个依据;
4.哪6大类问题不可以问? 要表达别人听得懂的话;
5.提问注意的“3不谈”,“4不讲”;
6.客户需求分析手册制定的6个步骤;
找对方向,事半功倍,为什么找这个客户?
时间没对,努力白费,为什么这个时候找?
找对人,说对话,为什么找这个人?
为什么推荐这个产品?给客户需要的,而不是自己想给的;
为什么给这样的服务? 客户看重不是产品,而是使用价值;
为什么报这个价? 在客户的预算与同行之间找到平衡;
7.为什么还这个价?关注竞争对手,调整自己的策略;
第二章 如何正确推荐产品
思考:
1、为什么我满足客户所提出的要求,客户却还需要考虑一下?
2、为什么客户不相信我质量与服务的承诺?
3、面对客户提出高端产品的要求,而我只有低端产品,怎么办?
4、如何推荐产品才能让客户感觉到我们跟别人不一样;
第一节 为什么需要我们正确地推荐产品?
1、客户往往对自己深层次的问题并不清楚;
2、客户的提出的要求可能是模糊或抽象,有的仅仅提出方向,不要局限于客户明显的问题,头痛医头,脚痛医脚;
3、客户往往会以我们竞品给他的条件要求我们;
4、满足客户提出的要求,是引导客户在不同公司之间做比较,而不在我公司做出决策;
第二节 如何帮助客户建立“排他性”的采购标准?
案例:客户关心的是你如何保证你的质量和服务水平
1、打仗就是打后勤,推荐产品中常用的34项内容;
2、产品的功能与客户需要解决的问题要相对应;客户喜欢提供解决方案的人,而不仅提供工具的人;
3、如何给竞争对手业务员设置障碍?
第三节 见什么人,说什么话;
不同情况下如何讲?时间、能力、精力、兴趣、文化水平、不同的职位等;
1. 什么情况下偏重于理性说服,打动别人的脑?
2. 什么情况下偏重于情感说服,打动别人的心?
3. 何种情况下只讲优势不讲劣势?
4. 何种情况下即讲优势又讲劣势?
第三章如何有效处理异议
思考
1、遇到小气、固执、粗鲁、啰嗦、刻薄、吹毛求疵、优柔寡断的客户应对?
2、客户直接挂电话,怎么办?
3、第二次见面,客户对我大发脾气,怎么办?
4、有一个行业,销售人员每天都会遇到大量的拒绝,为什么却没有任何人会沮丧?
5、客户就没有压力吗?知已知彼,客户采购时会有哪些压力?
6、为什么客户在上班时与下班后会表现不同的性格特征?
第一节:买卖双方的心情分析
1、如果一方比另一方更主动、更积极追求合作,则后者称为潜在客户
2、卖方知道某价一定不能卖,但买方不知道什么价不能买;
3、当卖方表现自己很想卖,买方会表现自己不想买;
4、买方还的价,并不一定是他认为商品就应该值这个价;
5、付钱之前,买方占优势,之后,卖方占优势;
第二节、理解客户购买时的心态;
1、客户谈判时常用7种试探技巧分析;
2、客户态度非常好,就是不下订单,为什么?
3、为什么有些客户让我们感觉高高在上,花钱是大爷?难道他们素质真的差?
4、客户自身会有哪6个压力?
案例:客户提出合理条件,是否我就应该降价?
案例:如何分清客户异议的真实性?
案例:当谈判出现僵局时怎么办?
案例:为什么我答应客户提出的所有的条件,反而失去了订单?
案例:客户一再地提出不同的条件,怎么处理?
案例:客户要求我降价时,怎么办?请分8个步骤处理
第三节 客户异议处理的5个区分
1、要区分“第一” 还是“唯一”
2、对客户要求的真伪进行鉴别;
3、要区分“情绪”还是“行为”
4、区分“假想”还是“事实”
5、区别问题的轻重,缓急;
第四章 如何建立良好的客情关系?
案例:销售工作需要疯狂、圆滑、奉承、见人说人话,见鬼说鬼话吗?
案例:生意不成仁义在,咱俩交个朋友,这句话应该由谁说?
案例:邀请客户吃饭,你应该怎么说?
案例:当客户表扬了你,你会怎么回答?
案例:我代表公司的形象,是否我应该表现自己很强势?
案例:为了获得客户的信任,我是否应该花重金包装自己?让自己很完美?
案例:是否需要处处表现自己很有礼貌?
案例:如何与企业高层、政府高层打交道?
第一节 做回真实和真诚的自己,表里如一
礼仪的目的是尊重别人,而不是伪装自己,礼仪中常见的错误;
1、演别人,再好的演技也会搞砸,想做别人的时候,你就会离自己很远;
2、不同的人,需求不同,越改越累,越改越气,只会把自己折磨得心浮气躁,不得人心;
3、以朋友的心态与客户交往,过多的商业化语言、行为、过多的礼仪只会让客户感觉到生硬、距离、排斥、公事公办,没有感情;
4、适当的暴露自己的缺点,越完美的人越不可信;
5、守时,守信,守约,及时传递进程与信息,让客户感觉到可控性;
6、销售不是向客户笑,而是要让客户对自己笑;
第二节 感谢伤害我的人,是因为我自己错了;
1、一味顺从、推卸责任、理论交谈、谈论小事、无诚信;
2、当客户说过一段时间、以后、改天、回头、月底时,如何应对?
3、越完美的人越不可信,自我暴露的四个层次;
4、做好防错性的服务,签完合同仅仅是合作的开始;
指导客户如何使用;
跟踪产品使用的情况;
为客户在使用过程中提供指导建议;
积极解答客户在使用中提出的问题;
第四章团队配合
思考:
1.团队配合的前提是什么?是否任意两个人在一起都会有团队精神?
2.团队配合中为什么会出现扯皮的现象?
3.为什么公司花那么高成本让大家加深感情,但有些人之间还是有隔阂?
4.业绩好的人影响业绩差的人容易还是业绩差的影响业绩好的容易?
5.统一底薪好?还是差别化底薪好?如何让大家都觉得公平?
6.为什么有能力的不听话,听话的却没能力?
7.为什么有些人总是不按我要求的方法去做?
8.面对业绩总是很差的员工,到底是留还是开?
第一节团队配合的重要性
1.优秀的业务员业绩往往是普通的几十甚至上百倍;
2.提高成交的效率,不要杀敌一千,而自损八百;
3.优秀业务员缺时间,业绩普通的业务员缺能力,扬长避短,人尽其才;
4.把人力资源效益利用最大化;
5.打造完美的团队,让成员的缺点相互抵消;
第二节,如何开展团队配合
第一、能力互补
1.关注员工的能力,不要把未来寄托在员工未知的潜能上;
2.不要把员工塑造成同一类型的人,不把专才当全才用;
3.团队以能为本,销售岗位常见的14项技能;
4.售前、售中、售后人员要求与如何搭配?
5.案例:新员工有激情,但能力不足,老员工有能力,但激情不足,怎么办?
第二、利益关联
1.为什么成员会相互冷漠、互不关心、彼此封锁信息和资源?
2.为什么团队成员把团队的事不当回事?
3.如何才能让团队成员真心的为优秀的成员而高兴?
4.开除业绩差的员工,其他成员缺乏安全感怎么办?
5.如何才能让团队自动自发的努力工作?
第三节、不同客户喜欢不同风格的销售人员
1、 销售人员形象与举止,注意自己的形象;
2、 是否具备相似的背景,门当户对;
3、 是否具备相同的认识,道不同不相为盟;
4、 是否“投其所好”,话不投机半句多;
5、 赞美,喜欢对方,我们同样对喜欢我们的人有好感;
先交流感情,增进互信,欲速则不达;
6、 是否对销售人员熟悉,销售最忌讳交浅言深;
初次见面就企图跟别人成为朋友的行为很幼稚;
初次见面就暗示好处的行为很肤浅;
刚见面就强调价格很便宜的行为很愚蠢;
7、 销售人员是否具备亲和力,别人的脸是自己的一面镜子;
成交并不取决于说理,而是取决于心情
8、 销售人员是否值得信赖。
第六章 新客户开发
案例:为什么客户一开始很有兴趣,但迟迟不下单?
案例:前天明明说不买的客户居然今天却买了,客户的话能相信吗?
案例:客户答应买我司的产品,却突然变卦买别人的了,为什么?
案例:为什么我们会买自己没有兴趣的而且并不需要的产品?
一、客户是根据自己所投入的精力、金钱来确定自己的态度;
二、如何才能引导客户作自我说服?
1.不要轻易给客户下结论,谁会买,谁不会买
2.态度上的变化叫说服,行为上的变化叫接受;
3.我们都喜欢为我们自己的行为找理由,却不善于做我们已找到理由的事;
4.客户是发现了自己的需求,“发现”的依据是自己的行为;
5.案例:合同签订后,应该问哪4句话,提升客户忠诚度?
第七章 自我激励
1.做销售工作赚钱最快,且最容易得到老板的重视、同事的尊重;
2.不要把第一次见面看成最后一次,工作要积极但不要着急;
3.不是成功太慢,而是放弃太快,钱是给内行的人赚的;
4.不要报着试试看的心态,企图一夜暴富的投机心态让客户反感;
5.不是有希望才坚持,而是坚持了才有希望;
6.付出才会拥有,而不是拥有才付出;做了才会,而不是会了才做;
7.好工作是做出来的,不是找出来的,不要把自己托付给公司,而要独立成长;
8.尝试不同的工作方法,而不是多年重复使用一种方式,具备试错的精神;
9.工作可以出错,但不可以不做,世界上最危险的莫过于原地不动;
10.不要把未来寄托在自己一无所知的行业上,做好目前的工作;
4 years, 4 months
[ndctl PATCH] test, libndctl: check btt size
by Dan Williams
Now that the kernel reports the size of the btt, lets check that the
size stays constant across kernel updates. I.e. if we inadvertently
introduce a change that causes the btt to reduce the effective capacity
of the block device, this test is meant to catch it.
Cc: Vishal Verma <vishal.l.verma(a)intel.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
test/libndctl.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/test/libndctl.c b/test/libndctl.c
index 5f86addc5c7e..e36fe8a4fe6f 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -937,6 +937,68 @@ static int check_pfn_create(struct ndctl_region *region,
return rc;
}
+static int check_btt_size(struct ndctl_btt *btt)
+{
+ struct ndctl_namespace *ndns = ndctl_btt_get_namespace(btt);
+ unsigned long long ns_size = ndctl_namespace_get_size(ndns);
+ unsigned long sect_size = ndctl_btt_get_sector_size(btt);
+ unsigned long long actual, expect;
+ int size_select, sect_select;
+ unsigned long long expect_table[][2] = {
+ [0] = {
+ [0] = 0x11b4400,
+ [1] = 0x8da2000,
+ },
+ [1] = {
+ [0] = 0x13b0400,
+ [1] = 0x9d82000,
+ },
+ [2] = {
+ [0] = 0x1aa2600,
+ [1] = 0xd513000,
+ },
+ };
+
+ if (sect_size >= SZ_4K)
+ sect_select = 1;
+ else if (sect_size >= 512)
+ sect_select = 0;
+ else {
+ fprintf(stderr, "%s: %s unexpected sector size: %lx\n",
+ __func__, ndctl_btt_get_devname(btt),
+ sect_size);
+ return -ENXIO;
+ }
+
+ switch (ns_size) {
+ case SZ_18M:
+ size_select = 0;
+ break;
+ case SZ_20M:
+ size_select = 1;
+ break;
+ case SZ_27M:
+ size_select = 2;
+ break;
+ default:
+ fprintf(stderr, "%s: %s unexpected namespace size: %llx\n",
+ __func__, ndctl_namespace_get_devname(ndns),
+ ns_size);
+ break;
+ }
+
+ expect = expect_table[size_select][sect_select];
+ actual = ndctl_btt_get_size(btt);
+ if (expect != actual) {
+ fprintf(stderr, "%s: namespace: %s unexpected size: %llx (expected: %llx)\n",
+ ndctl_btt_get_devname(btt),
+ ndctl_namespace_get_devname(ndns), actual, expect);
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
static int check_btt_create(struct ndctl_region *region, struct ndctl_namespace *ndns,
struct namespace *namespace)
{
@@ -982,6 +1044,10 @@ static int check_btt_create(struct ndctl_region *region, struct ndctl_namespace
fprintf(stderr, "%s: expected safe mode got: %d\n",
devname, mode);
+ rc = check_btt_size(btt);
+ if (rc)
+ goto err;
+
if (btt_seed == ndctl_region_get_btt_seed(region)
&& btt == btt_seed) {
fprintf(stderr, "%s: failed to advance btt seed\n",
4 years, 5 months
[PATCH] mm: silently skip readahead for DAX inodes
by Ross Zwisler
For DAX inodes we need to be careful to never have page cache pages in the
mapping->page_tree. This radix tree should be composed only of DAX
exceptional entries and zero pages.
ltp's readahead02 test was triggering a warning because we were trying to
insert a DAX exceptional entry but found that a page cache page had already
been inserted into the tree. This page was being inserted into the radix
tree in response to a readahead(2) call.
Readahead doesn't make sense for DAX inodes, but we don't want it to report
a failure either. Instead, we just return success and don't do any work.
Signed-off-by: Ross Zwisler <ross.zwisler(a)linux.intel.com>
Reported-by: Jeff Moyer <jmoyer(a)redhat.com>
Cc: stable(a)vger.kernel.org
---
mm/readahead.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/mm/readahead.c b/mm/readahead.c
index 65ec288..a9ba1be 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -8,6 +8,7 @@
*/
#include <linux/kernel.h>
+#include <linux/dax.h>
#include <linux/gfp.h>
#include <linux/export.h>
#include <linux/blkdev.h>
@@ -544,6 +545,9 @@ do_readahead(struct address_space *mapping, struct file *filp,
if (!mapping || !mapping->a_ops)
return -EINVAL;
+ if (dax_mapping(mapping))
+ return 0;
+
return force_page_cache_readahead(mapping, filp, index, nr);
}
--
2.9.0
4 years, 5 months
[ndctl PATCH] test, device-dax: validate MAP_PRIVATE attempts fail
by Dan Williams
Device-DAX explicitly disallows MAP_PRIVATE mappings.
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
test/device-dax.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/test/device-dax.c b/test/device-dax.c
index 34ca284f2ef5..a14e2a95db7e 100644
--- a/test/device-dax.c
+++ b/test/device-dax.c
@@ -113,6 +113,12 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
return -ENXIO;
}
+ buf = mmap(NULL, 2UL << 20, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (buf != MAP_FAILED) {
+ fprintf(stderr, "%s: expected MAP_PRIVATE failure\n", path);
+ return -ENXIO;
+ }
+
buf = mmap(NULL, 2UL << 20, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
p = (int *) (buf + (1UL << 20));
*p = 0;
4 years, 5 months
[ndctl PATCH] test: add device-dax direct-i/o test
by Dan Williams
A recent kernel bug report [1], highlighted the need to test page
structure mappings and direct-i/o for device dax. Repurpose the
existing filesystem-dax test for this case.
[1]: https://lists.01.org/pipermail/linux-nvdimm/2016-August/006704.html
Cc: Toshi Kani <toshi.kani(a)hpe.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
test/Makefile.am | 1
test/dax-pmd.c | 147 +++++++++++++++++++++++++++++------------------------
test/device-dax.c | 10 ++++
3 files changed, 92 insertions(+), 66 deletions(-)
diff --git a/test.h b/test.h
index 331d4131e2c7..2940ac0f7396 100644
--- a/test.h
+++ b/test.h
@@ -16,7 +16,7 @@ void builtin_xaction_namespace_reset(void);
struct ndctl_ctx;
int test_parent_uuid(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx);
-int test_direct_io(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx);
+int test_dax_directio(int dax_fd, void *dax_addr, off_t offset);
int test_dpa_alloc(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx);
int test_libndctl(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx);
int test_blk_namespaces(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx);
diff --git a/test/Makefile.am b/test/Makefile.am
index d13c138bb28a..f0240fe5883a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -60,6 +60,7 @@ dax_errors_SOURCES = dax-errors.c
device_dax_SOURCES = \
device-dax.c \
dax-dev.c \
+ dax-pmd.c \
core.c \
../ndctl/builtin-xaction-namespace.c \
../ndctl/util/json.c
diff --git a/test/dax-pmd.c b/test/dax-pmd.c
index ff0c70e9ea47..47f254e398b2 100644
--- a/test/dax-pmd.c
+++ b/test/dax-pmd.c
@@ -10,84 +10,35 @@
#include <sys/ioctl.h>
#include <stdlib.h>
#include <linux/fs.h>
+#include <test.h>
#include <linux/fiemap.h>
#define NUM_EXTENTS 5
#define HPAGE_SIZE (2 << 20)
#define ALIGN(x, a) ((((unsigned long long) x) + (a - 1)) & ~(a - 1))
#define fail() fprintf(stderr, "%s: failed at: %d\n", __func__, __LINE__)
-#define faili(i) fprintf(stderr, "%s: failed at: %d: %ld\n", __func__, __LINE__, i)
+#define faili(i) fprintf(stderr, "%s: failed at: %d: %d\n", __func__, __LINE__, i)
#define TEST_FILE "test_dax_data"
-/* test_pmd assumes that fd references a pre-allocated + dax-capable file */
-static int test_pmd(int fd)
+int test_dax_directio(int dax_fd, void *dax_addr, off_t offset)
{
- unsigned long long m_align, p_align;
- int fd2 = -1, rc = -ENXIO;
- struct fiemap_extent *ext;
- void *base, *addr, *buf;
- struct fiemap *map;
- unsigned long i;
-
- if (fd < 0) {
- fail();
- return -ENXIO;
- }
-
- map = calloc(1, sizeof(struct fiemap)
- + sizeof(struct fiemap_extent) * NUM_EXTENTS);
- if (!map) {
- fail();
- return -ENXIO;
- }
+ int i, rc = -ENXIO;
+ void *buf;
if (posix_memalign(&buf, 4096, 4096) != 0)
- goto err_memalign;
-
- base = mmap(NULL, 4*HPAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (base == MAP_FAILED) {
- fail();
- goto err_mmap;
- }
- munmap(base, 4*HPAGE_SIZE);
-
- map->fm_start = 0;
- map->fm_length = -1;
- map->fm_extent_count = NUM_EXTENTS;
- rc = ioctl(fd, FS_IOC_FIEMAP, map);
- if (rc < 0) {
- fail();
- goto err_extent;
- }
-
- for (i = 0; i < map->fm_mapped_extents; i++) {
- ext = &map->fm_extents[i];
- fprintf(stderr, "[%ld]: l: %llx p: %llx len: %llx flags: %x\n",
- i, ext->fe_logical, ext->fe_physical,
- ext->fe_length, ext->fe_flags);
- if (ext->fe_length > 2 * HPAGE_SIZE) {
- fprintf(stderr, "found potential huge extent\n");
- break;
- }
- }
-
- if (i >= map->fm_mapped_extents) {
- fail();
- goto err_extent;
- }
-
- m_align = ALIGN(base, HPAGE_SIZE) - ((unsigned long) base);
- p_align = ALIGN(ext->fe_physical, HPAGE_SIZE) - ext->fe_physical;
+ return -ENOMEM;
for (i = 0; i < 3; i++) {
- rc = -ENXIO;
- addr = mmap((char *) base + m_align, 2*HPAGE_SIZE,
- PROT_READ|PROT_WRITE, MAP_SHARED, fd,
- ext->fe_logical + p_align);
+ void *addr = mmap(dax_addr, 2*HPAGE_SIZE,
+ PROT_READ|PROT_WRITE, MAP_SHARED, dax_fd,
+ offset);
+ int fd2;
+
if (addr == MAP_FAILED) {
faili(i);
break;
}
+ rc = -ENXIO;
fd2 = open(TEST_FILE, O_CREAT|O_TRUNC|O_DIRECT|O_RDWR,
DEFFILEMODE);
@@ -97,7 +48,7 @@ static int test_pmd(int fd)
break;
}
- fprintf(stderr, "%s: test: %ld\n", __func__, i);
+ fprintf(stderr, "%s: test: %d\n", __func__, i);
rc = 0;
switch (i) {
case 0: /* test O_DIRECT of unfaulted address */
@@ -131,8 +82,10 @@ static int test_pmd(int fd)
} else if (rc > 0) {
/* parent */
wait(&rc);
- if (rc != EXIT_SUCCESS)
+ rc = WEXITSTATUS(rc);
+ if (rc != EXIT_SUCCESS) {
faili(i);
+ }
} else
faili(i);
break;
@@ -151,15 +104,77 @@ static int test_pmd(int fd)
break;
}
+ free(buf);
+ return rc;
+}
+
+/* test_pmd assumes that fd references a pre-allocated + dax-capable file */
+static int test_pmd(int fd)
+{
+ unsigned long long m_align, p_align;
+ struct fiemap_extent *ext;
+ struct fiemap *map;
+ int rc = -ENXIO;
+ unsigned long i;
+ void *base;
+
+ if (fd < 0) {
+ fail();
+ return -ENXIO;
+ }
+
+ map = calloc(1, sizeof(struct fiemap)
+ + sizeof(struct fiemap_extent) * NUM_EXTENTS);
+ if (!map) {
+ fail();
+ return -ENXIO;
+ }
+
+ base = mmap(NULL, 4*HPAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (base == MAP_FAILED) {
+ fail();
+ goto err_mmap;
+ }
+ munmap(base, 4*HPAGE_SIZE);
+
+ map->fm_start = 0;
+ map->fm_length = -1;
+ map->fm_extent_count = NUM_EXTENTS;
+ rc = ioctl(fd, FS_IOC_FIEMAP, map);
+ if (rc < 0) {
+ fail();
+ goto err_extent;
+ }
+
+ for (i = 0; i < map->fm_mapped_extents; i++) {
+ ext = &map->fm_extents[i];
+ fprintf(stderr, "[%ld]: l: %llx p: %llx len: %llx flags: %x\n",
+ i, ext->fe_logical, ext->fe_physical,
+ ext->fe_length, ext->fe_flags);
+ if (ext->fe_length > 2 * HPAGE_SIZE) {
+ fprintf(stderr, "found potential huge extent\n");
+ break;
+ }
+ }
+
+ if (i >= map->fm_mapped_extents) {
+ fail();
+ goto err_extent;
+ }
+
+ m_align = ALIGN(base, HPAGE_SIZE) - ((unsigned long) base);
+ p_align = ALIGN(ext->fe_physical, HPAGE_SIZE) - ext->fe_physical;
+
+ rc = test_dax_directio(fd, (char *) base + m_align, ext->fe_logical
+ + p_align);
+
err_extent:
err_mmap:
- free(buf);
- err_memalign:
free(map);
return rc;
}
-int main(int argc, char *argv[])
+int __attribute__((weak)) main(int argc, char *argv[])
{
int fd, rc;
diff --git a/test/device-dax.c b/test/device-dax.c
index fdd138884522..34ca284f2ef5 100644
--- a/test/device-dax.c
+++ b/test/device-dax.c
@@ -117,6 +117,16 @@ static int test_device_dax(int loglevel, struct ndctl_test *test,
p = (int *) (buf + (1UL << 20));
*p = 0;
+ if (ndctl_test_attempt(test, KERNEL_VERSION(4, 9, 0))) {
+ /* prior to 4.8-final this crashes */
+ rc = test_dax_directio(fd, NULL, 0);
+ if (rc) {
+ fprintf(stderr, "%s: failed dax direct-i/o\n",
+ ndctl_namespace_get_devname(ndns));
+ return rc;
+ }
+ }
+
rc = reset_device_dax(ndns);
if (rc < 0) {
fprintf(stderr, "%s: failed to reset device-dax instance\n",
4 years, 5 months
[PATCH] dax: fix device-dax region base
by Dan Williams
The data offset for a dax region needs to account for a reservation in
the resource range. Otherwise, device-dax is allowing mappings directly
into the memmap or device-info-block area with crash signatures like the
following:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
IP: [<ffffffff811ac851>] get_zone_device_page+0x11/0x30
Call Trace:
follow_devmap_pmd+0x298/0x2c0
follow_page_mask+0x275/0x530
__get_user_pages+0xe3/0x750
__gfn_to_pfn_memslot+0x1b2/0x450 [kvm]
? hrtimer_try_to_cancel+0x2c/0x120
? kvm_read_l1_tsc+0x55/0x60 [kvm]
try_async_pf+0x66/0x230 [kvm]
? kvm_host_page_size+0x90/0xa0 [kvm]
tdp_page_fault+0x130/0x280 [kvm]
kvm_mmu_page_fault+0x5f/0xf0 [kvm]
handle_ept_violation+0x94/0x180 [kvm_intel]
vmx_handle_exit+0x1d3/0x1440 [kvm_intel]
? atomic_switch_perf_msrs+0x6f/0xa0 [kvm_intel]
? vmx_vcpu_run+0x2d1/0x490 [kvm_intel]
kvm_arch_vcpu_ioctl_run+0x81d/0x16a0 [kvm]
? wake_up_q+0x44/0x80
kvm_vcpu_ioctl+0x33c/0x620 [kvm]
? __vfs_write+0x37/0x160
do_vfs_ioctl+0xa2/0x5d0
SyS_ioctl+0x79/0x90
entry_SYSCALL_64_fastpath+0x1a/0xa4
Cc: <stable(a)vger.kernel.org>
Cc: Andrew Morton <akpm(a)linux-foundation.org>
Fixes: ab68f2622136 ("/dev/dax, pmem: direct access to persistent memory")
Reported-by: Abhilash Kumar Mulumudi <m.abhilash-kumar(a)hpe.com>
Reported-by: Toshi Kani <toshi.kani(a)hpe.com>
Tested-by: Toshi Kani <toshi.kani(a)hpe.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
drivers/dax/pmem.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index dfb168568af1..1f01e98c83c7 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -116,6 +116,9 @@ static int dax_pmem_probe(struct device *dev)
if (rc)
return rc;
+ /* adjust the dax_region resource to the start of data */
+ res.start += le64_to_cpu(pfn_sb->dataoff);
+
nd_region = to_nd_region(dev->parent);
dax_region = alloc_dax_region(dev, nd_region->id, &res,
le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP);
4 years, 5 months
[PATCH] memremap: Fix NULL pointer BUG in get_zone_device_page()
by Toshi Kani
The following BUG was observed while starting up KVM with nvdimm
device as memory-backend-file to /dev/dax.
BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
IP: [<ffffffff811ac851>] get_zone_device_page+0x11/0x30
Call Trace:
follow_devmap_pmd+0x298/0x2c0
follow_page_mask+0x275/0x530
__get_user_pages+0xe3/0x750
__gfn_to_pfn_memslot+0x1b2/0x450 [kvm]
? hrtimer_try_to_cancel+0x2c/0x120
? kvm_read_l1_tsc+0x55/0x60 [kvm]
try_async_pf+0x66/0x230 [kvm]
? kvm_host_page_size+0x90/0xa0 [kvm]
tdp_page_fault+0x130/0x280 [kvm]
kvm_mmu_page_fault+0x5f/0xf0 [kvm]
handle_ept_violation+0x94/0x180 [kvm_intel]
vmx_handle_exit+0x1d3/0x1440 [kvm_intel]
? atomic_switch_perf_msrs+0x6f/0xa0 [kvm_intel]
? vmx_vcpu_run+0x2d1/0x490 [kvm_intel]
kvm_arch_vcpu_ioctl_run+0x81d/0x16a0 [kvm]
? wake_up_q+0x44/0x80
kvm_vcpu_ioctl+0x33c/0x620 [kvm]
? __vfs_write+0x37/0x160
do_vfs_ioctl+0xa2/0x5d0
SyS_ioctl+0x79/0x90
entry_SYSCALL_64_fastpath+0x1a/0xa4
devm_memremap_pages() calls for_each_device_pfn() to walk through
all pfns in page_map. pfn_first(), however, returns a wrong pfn
that leaves page->pgmap uninitialized.
Since arch_add_memory() has set up direct mappings to the NVDIMM
range with altmap, pfn_first() should not modify the start pfn.
Change pfn_first() to simply return pfn of res->start.
Reported-and-tested-by: Abhilash Kumar Mulumudi <m.abhilash-kumar(a)hpe.com>
Signed-off-by: Toshi Kani <toshi.kani(a)hpe.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Cc: Andrew Morton <akpm(a)linux-foundation.org>
Cc: Ard Biesheuvel <ard.biesheuvel(a)linaro.org>
Cc: Brian Starkey <brian.starkey(a)arm.com>
---
kernel/memremap.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/kernel/memremap.c b/kernel/memremap.c
index 251d16b..50ea577 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -210,15 +210,9 @@ static void pgmap_radix_release(struct resource *res)
static unsigned long pfn_first(struct page_map *page_map)
{
- struct dev_pagemap *pgmap = &page_map->pgmap;
const struct resource *res = &page_map->res;
- struct vmem_altmap *altmap = pgmap->altmap;
- unsigned long pfn;
- pfn = res->start >> PAGE_SHIFT;
- if (altmap)
- pfn += vmem_altmap_offset(altmap);
- return pfn;
+ return res->start >> PAGE_SHIFT;
}
static unsigned long pfn_end(struct page_map *page_map)
4 years, 5 months
[ndctl PATCH 0/3] ndctl: nvdimm notification tests
by Dan Williams
Add a new api, ndctl_dimm_get_health_eventfd(), and test that the kernel
signals an event on that file descriptor after a smart-threshold
command.
Also, include a new gate for the SMART verification test to await when
nfit_test is updated to emit the new v1.2 format of the SMART DSM
payload.
---
Dan Williams (3):
test: gate SMART payload verification on v4.9
ndctl: add ndctl_dimm_get_health_eventfd() api
test: validate ndctl_dimm_get_health_eventfd()
ndctl/lib/libndctl.c | 11 +++++++++
ndctl/lib/libndctl.sym | 1 +
ndctl/libndctl.h.in | 1 +
test/libndctl.c | 61 ++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 69 insertions(+), 5 deletions(-)
4 years, 5 months
SUSE B2B Conference List
by Lissa Nelson
Hi,
I hope all is well with you.
Would you be interested in obtaining updated Suse Tradeshow contact information for your marketing campaigns?
We provide direct marketing, telemarketing leads, data appending solutions, Data appending solutions, Center Analytics, Analytics and Automation Software, Partners, Sponsors and much more, all over the world!
Note: If Suse users are not relevant to you, Please reply with your target audience, or the industry you'd prefer to target with your marketing campaigns.We have all types of target markets available.
Please let me know your thoughts, and I will get back to you with additional information and/or to help you place your order today.
Thanks,
Lissa Nelson
Database coordinator
List acquisition | Technology Lists | Email/Data Appending | Search Engine Optimization
4 years, 5 months