mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Taku Izumi <izumi.taku@jp.fujitsu.com>
Cc: linux-kernel@vger.kernel.org, mingo@redhat.com, acme@kernel.org,
	hpa@zytor.com, x86@kernel.org, jolsa@redhat.com
Subject: Re: [PATCH v2][RESEND] perf, x86: Fix multi-segment problem of perf_event_intel_uncore
Date: Tue, 1 Sep 2015 13:15:33 +0200	[thread overview]
Message-ID: <20150901111533.GQ19282@twins.programming.kicks-ass.net> (raw)
In-Reply-To: <1440672872-129663-1-git-send-email-izumi.taku@jp.fujitsu.com>

On Thu, Aug 27, 2015 at 07:54:32PM +0900, Taku Izumi wrote:
> This patch fixes ths problem by introducing segment-aware pci2phy_map instead.
> 
>  v1 -> v2:
>    - Extract method named uncore_pcibus_to_physid to avoid repetetion of
>      retrieving phys_id code

So close and yet so far...

> +	raw_spin_lock(&pci2phy_map_lock);
> +	list_for_each_entry(map, &pci2phy_map_head, list) {
> +		if (map->segment == segment) {
> +			found = true;
> +			break;
> +		}
> +	}
> +	if (!found) {
> +		map = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL);
> +		if (map) {
> +			map->segment = segment;
> +			map->pbus_to_physid[bus] = 0;
> +			list_add_tail(&map->list, &pci2phy_map_head);
> +		}
> +	} else {
> +		map->pbus_to_physid[bus] = 0;
> +	}
> +	raw_spin_unlock(&pci2phy_map_lock);

> +
> +		segment = pci_domain_nr(ubox_dev->bus);
> +		raw_spin_lock(&pci2phy_map_lock);
> +		list_for_each_entry(map, &pci2phy_map_head, list) {
> +			if (map->segment == segment) {
> +				found = true;
>  				break;
>  			}
>  		}
> +		if (!found) {
> +			map = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL);
> +			if (map) {
> +				map->segment = segment;
> +				list_add_tail(&map->list, &pci2phy_map_head);
> +			}
> +		}
> +		if (map) {
> +			/*
> +			 * every three bits in the Node ID mapping register
> +			 * maps to a particular node.
> +			 */
> +			for (i = 0; i < 8; i++) {
> +				if (nodeid == ((config >> (3 * i)) & 0x7)) {
> +					map->pbus_to_physid[bus] = i;
> +					break;
> +				}
> +			}
> +
> +		}
> +		raw_spin_unlock(&pci2phy_map_lock);
>  	}

Nothing there strikes you as repetitive ?

Also, no mention on the -ENOMEM handling, and you simply _CANNOT_ do a
GFP_KERNEL alloc while holding a spinlock, so I bet you didn't actually
test the patch either.

Maybe something like the below? Equally untested.

---

--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -23,8 +23,8 @@ struct event_constraint uncore_constrain
 
 int uncore_pcibus_to_physid(struct pci_bus *bus)
 {
-	int phys_id = -1;
 	struct pci2phy_map *map;
+	int phys_id = -1;
 
 	raw_spin_lock(&pci2phy_map_lock);
 	list_for_each_entry(map, &pci2phy_map_head, list) {
@@ -38,6 +38,26 @@ int uncore_pcibus_to_physid(struct pci_b
 	return phys_id;
 }
 
+struct __find_pci2phy(int segment)
+{
+	struct pci2phy_map *map;
+
+	lockdep_assert_held(&pci2phy_map_lock);
+
+	list_for_each_entry(map, &pci2phy_map_head, list) {
+		if (map->segment == segment)
+			return map;
+	}
+
+	map = kmalloc(sizeof(struct pci2phy_map), GFP_ATOMIC);
+	if (map) {
+		map->segment = segment;
+		list_add_tail(&map->list, &pci2phy_map_head);
+	}
+
+	return map;
+}
+
 ssize_t uncore_event_show(struct kobject *kobj,
 			  struct kobj_attribute *attr, char *buf)
 {
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
@@ -433,22 +433,12 @@ static int snb_pci2phy_map_init(int devi
 	segment = pci_domain_nr(dev->bus);
 
 	raw_spin_lock(&pci2phy_map_lock);
-	list_for_each_entry(map, &pci2phy_map_head, list) {
-		if (map->segment == segment) {
-			found = true;
-			break;
-		}
-	}
-	if (!found) {
-		map = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL);
-		if (map) {
-			map->segment = segment;
-			map->pbus_to_physid[bus] = 0;
-			list_add_tail(&map->list, &pci2phy_map_head);
-		}
-	} else {
-		map->pbus_to_physid[bus] = 0;
+	map = __find_phy2pci(segment);
+	if (!map) {
+		raw_spin_unlock(&pci2phy_map_lock);
+		return -ENOMEM;
 	}
+	map->pbus_to_physid[bus] = 0;
 	raw_spin_unlock(&pci2phy_map_lock);
 
 	pci_dev_put(dev);
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
@@ -1112,31 +1112,21 @@ static int snbep_pci2phy_map_init(int de
 
 		segment = pci_domain_nr(ubox_dev->bus);
 		raw_spin_lock(&pci2phy_map_lock);
-		list_for_each_entry(map, &pci2phy_map_head, list) {
-			if (map->segment == segment) {
-				found = true;
-				break;
-			}
-		}
-		if (!found) {
-			map = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL);
-			if (map) {
-				map->segment = segment;
-				list_add_tail(&map->list, &pci2phy_map_head);
-			}
+		map = __find_pci2phy(segment);
+		if (!map) {
+			err = -ENOMEM;
+			break;
 		}
-		if (map) {
-			/*
-			 * every three bits in the Node ID mapping register
-			 * maps to a particular node.
-			 */
-			for (i = 0; i < 8; i++) {
-				if (nodeid == ((config >> (3 * i)) & 0x7)) {
-					map->pbus_to_physid[bus] = i;
-					break;
-				}
-			}
 
+		/*
+		 * every three bits in the Node ID mapping register
+		 * maps to a particular node.
+		 */
+		for (i = 0; i < 8; i++) {
+			if (nodeid == ((config >> (3 * i)) & 0x7)) {
+				map->pbus_to_physid[bus] = i;
+				break;
+			}
 		}
 		raw_spin_unlock(&pci2phy_map_lock);
 	}

  reply	other threads:[~2015-09-01 11:15 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-27 10:54 Taku Izumi
2015-09-01 11:15 ` Peter Zijlstra [this message]
2015-09-01 11:31   ` Ingo Molnar
2015-09-01 11:39     ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150901111533.GQ19282@twins.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=acme@kernel.org \
    --cc=hpa@zytor.com \
    --cc=izumi.taku@jp.fujitsu.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome