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=-9.0 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT 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 442B6C4321B for ; Thu, 25 Apr 2019 14:00:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 27652206BA for ; Thu, 25 Apr 2019 14:00:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="Aji4m0di" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728908AbfDYOAL (ORCPT ); Thu, 25 Apr 2019 10:00:11 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:41836 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728327AbfDYOAJ (ORCPT ); Thu, 25 Apr 2019 10:00:09 -0400 Received: by mail-wr1-f67.google.com with SMTP id c12so24326791wrt.8 for ; Thu, 25 Apr 2019 07:00:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xA1O9Hp3l5lMCcprC6eoIxtVWz+9nSVtmusO6Rb+iWQ=; b=Aji4m0diZwRS5NNrTqqCUCxIwePR2J+hgb+KuPDUBSFUOBwqDu0aREGGetSZvekseX p01/yi3reaKk6ReFjompvvQXMPBCYBgcY7XgeqPIxa6b/KqA9Tw4ZW9Pa2DAU3ivRF7o iVIgPmI62arfiZBU+rxPSuyxtwkjA7rTGZWwCyUaT8x1FYvjj5h+Xbfw792a/Ns7okhV N9AOek9TKLE71koDCscL1OQx7OV8jeEP4+EtRUGIXndjDme0a53hNEsEMhAgyunSOu2m OjHex1uR+srAb6zBHPbTtbQfMI/ybWRxHtx9NnVZ8fI3nNHf4W10o+CaPxQjgvfdUoki v3/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xA1O9Hp3l5lMCcprC6eoIxtVWz+9nSVtmusO6Rb+iWQ=; b=TPvhYvQyMY3mlftPvyldlFPwr9ILUpWrneNG9IFCee+p46Lku/l2QHw1QtAly95HqQ h2YQSCUjp6GXHjASCdh6U2hDouWNVi7yUlmJXReRny+9v6jpVApsaEB9BMCd8+gvuQgl drfyHxHRDgjFYq4wyFLkea+bQ0U4ZjHb7iutzd70DNvN41sBT0lFSg8jf8onZ1DdLoUW C3xMp4dXj5bdmXsdj9oTsCgpc4nwAKiHu7tlo9eShIKkGboeJYuBg4htCAYq+RRJz8iz MiOxWe+2qgws3Z36rYDfC/VRDog2GbvtOIQiT/qIxqHsjRe1a5/cx9YsX4pmnp/ZE9OY oIGg== X-Gm-Message-State: APjAAAUF5e/f8bwsTlXyEzTf5/SY/eHOQEFTByA3AX2hfnLHzy+JzdiI BUdd34bmreBn6UpAXb+UAegBs7504Sk= X-Google-Smtp-Source: APXvYqzDu1JvsNXh/2c9obzHiwIJesQBTpjFhEdHDgLYxCdMdePQulQqykCum9fRiZSywUFtMTJ6sw== X-Received: by 2002:a5d:550c:: with SMTP id b12mr11554615wrv.318.1556200807349; Thu, 25 Apr 2019 07:00:07 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id n18sm18777271wrt.16.2019.04.25.07.00.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 25 Apr 2019 07:00:07 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, mlxsw@mellanox.com, jakub.kicinski@netronome.com, dsahern@gmail.com Subject: [patch net-next v4 08/16] netdevsim: add bus attributes to add new and delete devices Date: Thu, 25 Apr 2019 15:59:48 +0200 Message-Id: <20190425135956.3970-9-jiri@resnulli.us> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190425135956.3970-1-jiri@resnulli.us> References: <20190425135956.3970-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Add a way to add new netdevsim device on netdevsim bus and also to delete existing netdevsim device from the bus. Track the bus devices in using a list. Signed-off-by: Jiri Pirko --- v3->v4: - fix wrapping of function declararions according to Jakub's rules. --- drivers/net/netdevsim/bus.c | 97 ++++++++++++++++++++++++++++++- drivers/net/netdevsim/netdev.c | 2 +- drivers/net/netdevsim/netdevsim.h | 4 +- 3 files changed, 99 insertions(+), 4 deletions(-) diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c index c50c5ea90555..c30692f17374 100644 --- a/drivers/net/netdevsim/bus.c +++ b/drivers/net/netdevsim/bus.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include #include @@ -13,6 +15,8 @@ #include "netdevsim.h" static DEFINE_IDA(nsim_bus_dev_ids); +static LIST_HEAD(nsim_bus_dev_list); +static DEFINE_MUTEX(nsim_bus_dev_list_lock); static struct nsim_bus_dev *to_nsim_bus_dev(struct device *dev) { @@ -113,6 +117,83 @@ static struct device_type nsim_bus_dev_type = { .release = nsim_bus_dev_release, }; +static ssize_t +new_device_store(struct bus_type *bus, const char *buf, size_t count) +{ + struct nsim_bus_dev *nsim_bus_dev; + unsigned int port_count; + unsigned int id; + int err; + + err = sscanf(buf, "%u %u", &id, &port_count); + switch (err) { + case 1: + port_count = 1; + /* pass through */ + case 2: + if (id > INT_MAX) { + pr_err("Value of \"id\" is too big.\n"); + return -EINVAL; + } + break; + default: + pr_err("Format for adding new device is \"id port_count\" (uint uint).\n"); + return -EINVAL; + } + nsim_bus_dev = nsim_bus_dev_new(id, port_count); + if (IS_ERR(nsim_bus_dev)) + return PTR_ERR(nsim_bus_dev); + + mutex_lock(&nsim_bus_dev_list_lock); + list_add_tail(&nsim_bus_dev->list, &nsim_bus_dev_list); + mutex_unlock(&nsim_bus_dev_list_lock); + + return count; +} +static BUS_ATTR_WO(new_device); + +static ssize_t +del_device_store(struct bus_type *bus, const char *buf, size_t count) +{ + struct nsim_bus_dev *nsim_bus_dev, *tmp; + unsigned int id; + int err; + + err = sscanf(buf, "%u", &id); + switch (err) { + case 1: + if (id > INT_MAX) { + pr_err("Value of \"id\" is too big.\n"); + return -EINVAL; + } + break; + default: + pr_err("Format for deleting device is \"id\" (uint).\n"); + return -EINVAL; + } + + err = -ENOENT; + mutex_lock(&nsim_bus_dev_list_lock); + list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) { + if (nsim_bus_dev->dev.id != id) + continue; + list_del(&nsim_bus_dev->list); + nsim_bus_dev_del(nsim_bus_dev); + err = 0; + break; + } + mutex_unlock(&nsim_bus_dev_list_lock); + return !err ? count : err; +} +static BUS_ATTR_WO(del_device); + +static struct attribute *nsim_bus_attrs[] = { + &bus_attr_new_device.attr, + &bus_attr_del_device.attr, + NULL +}; +ATTRIBUTE_GROUPS(nsim_bus); + int nsim_num_vf(struct device *dev) { struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); @@ -123,10 +204,11 @@ int nsim_num_vf(struct device *dev) static struct bus_type nsim_bus = { .name = DRV_NAME, .dev_name = DRV_NAME, + .bus_groups = nsim_bus_groups, .num_vf = nsim_num_vf, }; -struct nsim_bus_dev *nsim_bus_dev_new(void) +struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count) { struct nsim_bus_dev *nsim_bus_dev; int err; @@ -135,12 +217,15 @@ struct nsim_bus_dev *nsim_bus_dev_new(void) if (!nsim_bus_dev) return ERR_PTR(-ENOMEM); - err = ida_alloc(&nsim_bus_dev_ids, GFP_KERNEL); + err = ida_alloc_range(&nsim_bus_dev_ids, + id == ~0 ? 0 : id, id, GFP_KERNEL); if (err < 0) goto err_nsim_bus_dev_free; nsim_bus_dev->dev.id = err; nsim_bus_dev->dev.bus = &nsim_bus; nsim_bus_dev->dev.type = &nsim_bus_dev_type; + nsim_bus_dev->port_count = port_count; + err = device_register(&nsim_bus_dev->dev); if (err) goto err_nsim_bus_dev_id_free; @@ -185,6 +270,14 @@ int nsim_bus_init(void) void nsim_bus_exit(void) { + struct nsim_bus_dev *nsim_bus_dev, *tmp; + + mutex_lock(&nsim_bus_dev_list_lock); + list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) { + list_del(&nsim_bus_dev->list); + nsim_bus_dev_del(nsim_bus_dev); + } + mutex_unlock(&nsim_bus_dev_list_lock); driver_unregister(&nsim_driver); bus_unregister(&nsim_bus); } diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index 3407b009929e..37a442ffcb8b 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -386,7 +386,7 @@ static int nsim_newlink(struct net *src_net, struct net_device *dev, if (IS_ERR(ns->sdev)) return PTR_ERR(ns->sdev); - ns->nsim_bus_dev = nsim_bus_dev_new(); + ns->nsim_bus_dev = nsim_bus_dev_new(~0, 0); if (IS_ERR(ns->nsim_bus_dev)) { err = PTR_ERR(ns->nsim_bus_dev); goto err_sdev_put; diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index 528d1e7d3e6b..8d61fcb55f39 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -196,11 +196,13 @@ struct nsim_vf_config { struct nsim_bus_dev { struct device dev; + struct list_head list; + unsigned int port_count; unsigned int num_vfs; struct nsim_vf_config *vfconfigs; }; -struct nsim_bus_dev *nsim_bus_dev_new(void); +struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count); void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev); int nsim_bus_init(void); void nsim_bus_exit(void); -- 2.17.2