public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Yinghai Lu <yinghai@kernel.org>
To: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@elte.hu>,
	"H. Peter Anvin" <hpa@zytor.com>, Tony Luck <tony.luck@intel.com>
Cc: linux-kernel@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>,
	Joerg Roedel <joro@8bytes.org>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Subject: [PATCH v3 7/8] irq: Add irq_alloc_reserved_desc()
Date: Mon,  5 May 2014 18:33:25 -0700	[thread overview]
Message-ID: <1399340006-31550-8-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1399340006-31550-1-git-send-email-yinghai@kernel.org>

For ioapic hot-add support, it would be easy if we have continuous
irq numbers for hot added ioapic controller.

We can reserve irq range at first, and later allocate desc for those
pre-reserved irqs when they are needed.

The reasons for not allocating them during reserving:
1. only several pins of one ioapic are used, allocate for all pins, will
   waste memory for not used pins.
2. allocate later when is needed could make sure irq_desc is allocated
   on local node ram, as dev->node is set at that point.

-v2: update changelog by adding reasons, requested by Konrad.
-v3: according to tglx:
       separate core code change with arch code change.
       change function name to irq_alloc_reserved_desc.
       kill __irq_is_reserved().
       remove not need exports.
     according to Sebastian:
       spare one comments by put two functions together.
-v4: Fix the bug that tglx pointed out.
     irq_alloc_descs() should avoid reserved irqs.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
 include/linux/irq.h  |  3 ++
 kernel/irq/irqdesc.c | 97 ++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 2ba3245..97b60b9 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -608,10 +608,13 @@ int irq_mark_reserved_irqs(int irq, unsigned int from, unsigned int cnt);
 
 int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
 		struct module *owner);
+int __irq_alloc_reserved_desc(int at, int node, struct module *owner);
 
 /* use macros to avoid needing export.h for THIS_MODULE */
 #define irq_alloc_descs(irq, from, cnt, node)	\
 	__irq_alloc_descs(irq, from, cnt, node, THIS_MODULE)
+#define irq_alloc_reserved_desc_at(at, node)	\
+	__irq_alloc_reserved_desc(at, node, THIS_MODULE)
 
 #define irq_alloc_desc(node)			\
 	irq_alloc_descs(-1, 0, 1, node)
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index d55297a..7b2b83a 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -352,21 +352,11 @@ void irq_free_descs(unsigned int from, unsigned int cnt)
 }
 EXPORT_SYMBOL_GPL(irq_free_descs);
 
-/**
- * irq_alloc_descs - allocate and initialize a range of irq descriptors
- * @irq:	Allocate for specific irq number if irq >= 0
- * @from:	Start the search from this irq number
- * @cnt:	Number of consecutive irqs to allocate.
- * @node:	Preferred node on which the irq descriptor should be allocated
- * @owner:	Owning module (can be NULL)
- *
- * Returns the first irq number or error code
- */
-int __ref
-__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
-		  struct module *owner)
+/* Should be used with sparse_irq_lock */
+static int __irq_mark_allocated_irqs(int irq, unsigned int from,
+				     unsigned int cnt, int avoid_reserved)
 {
-	int start, ret;
+	int start;
 
 	if (!cnt)
 		return -EINVAL;
@@ -377,26 +367,55 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
 		from = irq;
 	}
 
-	mutex_lock(&sparse_irq_lock);
+	if (avoid_reserved) {
+		bitmap_or(reserved_or_allocated_irqs, reserved_irqs,
+			  allocated_irqs, IRQ_BITMAP_BITS);
 
-	start = bitmap_find_next_zero_area(allocated_irqs, IRQ_BITMAP_BITS,
-					   from, cnt, 0);
-	ret = -EEXIST;
-	if (irq >=0 && start != irq)
-		goto err;
+		start = bitmap_find_next_zero_area(reserved_or_allocated_irqs,
+							IRQ_BITMAP_BITS,
+							from, cnt, 0);
+	} else
+		start = bitmap_find_next_zero_area(allocated_irqs,
+							IRQ_BITMAP_BITS,
+							from, cnt, 0);
+
+	if (irq >= 0 && start != irq)
+		return -EEXIST;
 
 	if (start + cnt > nr_irqs) {
-		ret = irq_expand_nr_irqs(start + cnt);
-		if (ret)
-			goto err;
+		int ret = irq_expand_nr_irqs(start + cnt);
+
+		if (ret < 0)
+			return ret;
 	}
 
 	bitmap_set(allocated_irqs, start, cnt);
-	mutex_unlock(&sparse_irq_lock);
-	return alloc_descs(start, cnt, node, owner);
 
-err:
+	return start;
+}
+
+/**
+ * irq_alloc_descs - allocate and initialize a range of irq descriptors
+ * @irq:	Allocate for specific irq number if irq >= 0
+ * @from:	Start the search from this irq number
+ * @cnt:	Number of consecutive irqs to allocate.
+ * @node:	Preferred node on which the irq descriptor should be allocated
+ * @owner:	Owning module (can be NULL)
+ *
+ * Returns the first irq number or error code
+ */
+int __ref
+__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
+		  struct module *owner)
+{	int ret;
+
+	mutex_lock(&sparse_irq_lock);
+	ret = __irq_mark_allocated_irqs(irq, from, cnt, 1);
 	mutex_unlock(&sparse_irq_lock);
+
+	if (ret >= 0)
+		return alloc_descs(ret, cnt, node, owner);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(__irq_alloc_descs);
@@ -464,6 +483,32 @@ err:
 	return ret;
 }
 
+ /**
+ * __irq_alloc_reserved_desc - allocate irq descriptor for irq that is already reserved
+ * @irq:	Allocate for specific irq number if irq >= 0
+ * @node:	Preferred node on which the irq descriptor should be allocated
+ * @owner:	Owning module (can be NULL)
+ *
+ * Returns the irq number or error code
+ */
+int __ref __irq_alloc_reserved_desc(int irq, int node, struct module *owner)
+{
+	int ret = -EINVAL;
+
+	if (irq < 0 || irq >= nr_irqs)
+		return -EINVAL;
+
+	mutex_lock(&sparse_irq_lock);
+	if (test_bit(irq, reserved_irqs))
+		ret = __irq_mark_allocated_irqs(irq, irq, 1, 0);
+	mutex_unlock(&sparse_irq_lock);
+
+	if (ret >= 0)
+		return alloc_descs(ret, 1, node, owner);
+
+	return ret;
+}
+
 /**
  * irq_get_next_irq - get next allocated irq number
  * @offset:	where to start the search
-- 
1.8.4.5


  parent reply	other threads:[~2014-05-06  1:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-06  1:33 [PATCH v3 0/8] irq: core changes for x86 ioapic hotplug Yinghai Lu
2014-05-06  1:33 ` [PATCH v3 1/8] x86, irq: Remove not needed irq_reserve_irqs calling Yinghai Lu
2014-05-06  1:33 ` [PATCH v3 2/8] sh, irq: Remove irq_reserve_irq calling Yinghai Lu
2014-05-06  1:33 ` [PATCH v3 3/8] irq: Use irq_alloc_desc_at instead of irq_reserve_irq Yinghai Lu
2014-05-06  1:33 ` [PATCH v3 4/8] s390: Mark bits in allocated_irqs in general code Yinghai Lu
2014-05-06  1:33 ` [PATCH v3 5/8] irq: Kill irq_reserve_irq/irq_reserve_irqs Yinghai Lu
2014-05-06  1:33 ` [PATCH v3 6/8] irq: Add new reserved_irqs clear/mark functions Yinghai Lu
2014-05-06  1:33 ` Yinghai Lu [this message]
2014-05-06  1:33 ` [PATCH v3 8/8] irq: Do not free unallocated irq descriptors Yinghai Lu
2014-05-07  9:46 ` [PATCH v3 0/8] irq: core changes for x86 ioapic hotplug Ingo Molnar

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=1399340006-31550-8-git-send-email-yinghai@kernel.org \
    --to=yinghai@kernel.org \
    --cc=hpa@zytor.com \
    --cc=joro@8bytes.org \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=sebastian@breakpoint.cc \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    /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