From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79F31C04EBF for ; Mon, 3 Dec 2018 23:35:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4059520850 for ; Mon, 3 Dec 2018 23:35:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4059520850 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726101AbeLCXf6 (ORCPT ); Mon, 3 Dec 2018 18:35:58 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42980 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725968AbeLCXf4 (ORCPT ); Mon, 3 Dec 2018 18:35:56 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0EF973082193; Mon, 3 Dec 2018 23:35:55 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-120-188.rdu2.redhat.com [10.10.120.188]) by smtp.corp.redhat.com (Postfix) with ESMTP id B9833600C7; Mon, 3 Dec 2018 23:35:51 +0000 (UTC) From: jglisse@redhat.com To: linux-mm@kvack.org Cc: Andrew Morton , linux-kernel@vger.kernel.org, =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , "Rafael J . Wysocki" , Ross Zwisler , Dan Williams , Dave Hansen , Haggai Eran , Balbir Singh , "Aneesh Kumar K . V" , Benjamin Herrenschmidt , Felix Kuehling , Philip Yang , =?UTF-8?q?Christian=20K=C3=B6nig?= , Paul Blinzer , Logan Gunthorpe , John Hubbard , Ralph Campbell , Michal Hocko , Jonathan Cameron , Mark Hairgrove , Vivek Kini , Mel Gorman , Dave Airlie , Ben Skeggs , Andrea Arcangeli Subject: [RFC PATCH 04/14] mm/hms: add initiator to heterogeneous memory system infrastructure Date: Mon, 3 Dec 2018 18:34:59 -0500 Message-Id: <20181203233509.20671-5-jglisse@redhat.com> In-Reply-To: <20181203233509.20671-1-jglisse@redhat.com> References: <20181203233509.20671-1-jglisse@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Mon, 03 Dec 2018 23:35:55 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jérôme Glisse An initiator is anything that can initiate memory access, either a CPU or a device. Here CPUs and devices are treated as equals. See HMS Documentation/vm/hms.txt for further detail.. Signed-off-by: Jérôme Glisse Cc: Rafael J. Wysocki Cc: Ross Zwisler Cc: Dan Williams Cc: Dave Hansen Cc: Haggai Eran Cc: Balbir Singh Cc: Aneesh Kumar K.V Cc: Benjamin Herrenschmidt Cc: Felix Kuehling Cc: Philip Yang Cc: Christian König Cc: Paul Blinzer Cc: Logan Gunthorpe Cc: John Hubbard Cc: Ralph Campbell Cc: Michal Hocko Cc: Jonathan Cameron Cc: Mark Hairgrove Cc: Vivek Kini Cc: Mel Gorman Cc: Dave Airlie Cc: Ben Skeggs Cc: Andrea Arcangeli --- drivers/base/Makefile | 2 +- drivers/base/hms-initiator.c | 141 +++++++++++++++++++++++++++++++++++ include/linux/hms.h | 15 ++++ 3 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 drivers/base/hms-initiator.c diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 8e8092145f18..6a1b5ab667bd 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -12,7 +12,7 @@ obj-y += power/ obj-$(CONFIG_ISA_BUS_API) += isa.o obj-y += firmware_loader/ obj-$(CONFIG_NUMA) += node.o -obj-$(CONFIG_HMS) += hms.o hms-target.o +obj-$(CONFIG_HMS) += hms.o hms-target.o hms-initiator.o obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o ifeq ($(CONFIG_SYSFS),y) obj-$(CONFIG_MODULES) += module.o diff --git a/drivers/base/hms-initiator.c b/drivers/base/hms-initiator.c new file mode 100644 index 000000000000..08aa519427d6 --- /dev/null +++ b/drivers/base/hms-initiator.c @@ -0,0 +1,141 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * Authors: + * Jérôme Glisse + */ +/* Heterogeneous memory system (HMS) see Documentation/vm/hms.rst */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static inline struct hms_initiator *hms_object_to_initiator(struct hms_object *object) +{ + if (object == NULL) + return NULL; + + if (object->type != HMS_INITIATOR) + return NULL; + return container_of(object, struct hms_initiator, object); +} + +static inline struct hms_initiator *device_to_hms_initiator(struct device *device) +{ + if (device == NULL) + return NULL; + + return hms_object_to_initiator(to_hms_object(device)); +} + +struct hms_initiator *hms_initiator_find_locked(unsigned uid) +{ + struct hms_object *object = hms_object_find_locked(uid); + struct hms_initiator *initiator; + + initiator = hms_object_to_initiator(object); + if (initiator) + return initiator; + hms_object_put(object); + return NULL; +} + +struct hms_initiator *hms_initiator_find(unsigned uid) +{ + struct hms_object *object = hms_object_find(uid); + struct hms_initiator *initiator; + + initiator = hms_object_to_initiator(object); + if (initiator) + return initiator; + hms_object_put(object); + return NULL; +} + +static void hms_initiator_release(struct device *device) +{ + struct hms_initiator *initiator = device_to_hms_initiator(device); + + hms_object_release(&initiator->object); + kfree(initiator); +} + +static ssize_t hms_initiator_show_uid(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct hms_initiator *initiator = device_to_hms_initiator(device); + + if (initiator == NULL) + return -EINVAL; + + return sprintf(buf, "%d\n", initiator->object.uid); +} + +static DEVICE_ATTR(uid, 0444, hms_initiator_show_uid, NULL); + +static struct attribute *hms_initiator_attrs[] = { + &dev_attr_uid.attr, + NULL +}; + +static struct attribute_group hms_initiator_attr_group = { + .attrs = hms_initiator_attrs, +}; + +static const struct attribute_group *hms_initiator_attr_groups[] = { + &hms_initiator_attr_group, + NULL, +}; + +void hms_initiator_register(struct hms_initiator **initiatorp, + struct device *parent, int nid, + unsigned version) +{ + struct hms_initiator *initiator; + + *initiatorp = NULL; + initiator = kzalloc(sizeof(*initiator), GFP_KERNEL); + if (initiator == NULL) + return; + + initiator->nid = nid; + + if (hms_object_init(&initiator->object, parent, HMS_INITIATOR, version, + hms_initiator_release, hms_initiator_attr_groups)) + { + kfree(initiator); + initiator = NULL; + } + + *initiatorp = initiator; +} +EXPORT_SYMBOL(hms_initiator_register); + +void hms_initiator_unregister(struct hms_initiator **initiatorp) +{ + struct hms_initiator *initiator = *initiatorp; + + *initiatorp = NULL; + if (initiator == NULL) + return; + + hms_object_unregister(&initiator->object); +} +EXPORT_SYMBOL(hms_initiator_unregister); diff --git a/include/linux/hms.h b/include/linux/hms.h index 0568fdf6d479..7a2823493f63 100644 --- a/include/linux/hms.h +++ b/include/linux/hms.h @@ -67,6 +67,17 @@ struct hms_object *hms_object_find_locked(unsigned uid); struct hms_object *hms_object_find(unsigned uid); +struct hms_initiator { + struct hms_object object; + int nid; +}; + +void hms_initiator_register(struct hms_initiator **initiatorp, + struct device *parent, int nid, + unsigned version); +void hms_initiator_unregister(struct hms_initiator **initiatorp); + + struct hms_target { const struct hms_target_hbind *hbind; struct hms_object object; @@ -95,6 +106,10 @@ int hms_init(void); #else /* IS_ENABLED(CONFIG_HMS) */ +#define hms_initiator_register(initiatorp) +#define hms_initiator_unregister(initiatorp) + + #define hms_target_add_memory(target, size) #define hms_target_remove_memory(target, size) #define hms_target_register(targetp, nid, size) -- 2.17.2