Re: IDE DMA doesn't work with pata_via and compact flash card
On Thu, 11 Oct 2007 11:19:11 +0100, Alan Cox <[EMAIL PROTECTED]> wrote: >> ones, when using DMA. Turning off DMA for the old IDE drivers or >> patching ata_generic to handle my IDE controller and then deactivating >> DMA in the BIOS works, but then disk I/O is unbelievable slow.. do you >> have any idea how to fix it, so that DMA works? > > Does your CF/IDE adapter support DMA ? Thank you for your answer :) I thought CF/IDE adapters are mainly electrical adapters.. I've never seen one which explicitly states the modes it supports. On the other hand it says on the package: "Vista compatible" (whatever that means) Is there some way I can figure it out? I'll have a deeper look on the datasheet when I'm home again later, but I'm rather sure there wasn't anything mentioning supporting data transfer modes.. Best regards, Philipp - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: IDE DMA doesn't work with pata_via and compact flash card
On Thu, 11 Oct 2007 11:19:11 +0100, Alan Cox <[EMAIL PROTECTED]> wrote: >> ones, when using DMA. Turning off DMA for the old IDE drivers or >> patching ata_generic to handle my IDE controller and then deactivating >> DMA in the BIOS works, but then disk I/O is unbelievable slow.. do you >> have any idea how to fix it, so that DMA works? > > Does your CF/IDE adapter support DMA ? Oh well, you're right.. there are still some CF/IDE adapters which do not support DMA. I'll guess this is the problem then, so I'll return it to the shop. Best regards, Philipp - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Support for secure erase functionality
Dear Damien, Thank you for your feedback. > On 14. Sep 2017, at 10:46, Damien Le Moal wrote: […] > Writing once to a sector stored on spinning rust will *not* fully erase > the previous data. Part of the signal used for storing that data will > remain on the track (because the disk head is never perfectly aligned on > the track). With some signal processing work, the old data can be retrieved. > > You will need a *lot* of normal writes to make sure nothing remains of > the old data signal. Granted, even a single write will make it hard to > get to the old data, but it is possible nevertheless. Hence the standard > defined SANITIZE with cryptographic erase option to ensure that the old > data is really dead. We constructed our patch based on a paper called “Overwriting Hard Drive Data: The Great Wiping Controversy” which stated that a single overwrite of the data is sufficient. Nevertheless this should not be a solution to replace encryption but to improve data security when better techniques are not viable (e.g. travelling between countries while importing or exporting encrypted data may be prohibited without a license). > I think that a similar problem also exist for SSDs, and it is even worse > there since writing twice to the same logical sector does not even go to > the same physical sector. The old data is not even overwritten. We know about the problems regarding the data placement on SSDs, but there is very little we can do with code against the hardware controller of specific devices. On SSDs, you would probably want to use full disk encryption, because it should be no problem, when encrypted blocks are left on the drive. However in cases where encryption is too slow or not possible, this could improve data confidentiality. Best regards, Philipp
[PATCH] mfd: da9052-core: Fix interrupts reported to mfd child devices
The patch "mfd: da9052-core: Use regmap_irq_get_virq() and fix the probe" replaces the irq_base with the da9052_map_irq function but doesn't update the irq_base parameter to the mfd_add_devices call. This causes child devices to try and request IRQs with just the internal offset number. Signed-off-by: Philipp Zabel --- drivers/mfd/da9052-core.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index c96cdbc..0f12972 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -804,7 +804,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret); ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, - ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL); + ARRAY_SIZE(da9052_subdev_info), NULL, da9052_map_irq(da9052, 0), NULL); if (ret) { dev_err(da9052->dev, "mfd_add_devices failed: %d\n", ret); goto err; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 04/18] drbd: use the cached meta_dev_idx
From: Lars Ellenberg Now we have the cached meta_dev_idx member, we can get rid of a few rcu_read_lock() sections and rcu_dereference(). Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 32 +--- drivers/block/drbd/drbd_nl.c |7 +-- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index ee19ba2..6eecdec 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1777,9 +1777,9 @@ static inline void drbd_chk_io_error_(struct drbd_conf *mdev, * BTW, for internal meta data, this happens to be the maximum capacity * we could agree upon with our peer node. */ -static inline sector_t _drbd_md_first_sector(int meta_dev_idx, struct drbd_backing_dev *bdev) +static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev) { - switch (meta_dev_idx) { + switch (bdev->md.meta_dev_idx) { case DRBD_MD_INDEX_INTERNAL: case DRBD_MD_INDEX_FLEX_INT: return bdev->md.md_offset + bdev->md.bm_offset; @@ -1789,30 +1789,13 @@ static inline sector_t _drbd_md_first_sector(int meta_dev_idx, struct drbd_backi } } -static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev) -{ - int meta_dev_idx; - - rcu_read_lock(); - meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx; - rcu_read_unlock(); - - return _drbd_md_first_sector(meta_dev_idx, bdev); -} - /** * drbd_md_last_sector() - Return the last sector number of the meta data area * @bdev: Meta data block device. */ static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev) { - int meta_dev_idx; - - rcu_read_lock(); - meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx; - rcu_read_unlock(); - - switch (meta_dev_idx) { + switch (bdev->md.meta_dev_idx) { case DRBD_MD_INDEX_INTERNAL: case DRBD_MD_INDEX_FLEX_INT: return bdev->md.md_offset + MD_4kB_SECT -1; @@ -1840,18 +1823,13 @@ static inline sector_t drbd_get_capacity(struct block_device *bdev) static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev) { sector_t s; - int meta_dev_idx; - - rcu_read_lock(); - meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx; - rcu_read_unlock(); - switch (meta_dev_idx) { + switch (bdev->md.meta_dev_idx) { case DRBD_MD_INDEX_INTERNAL: case DRBD_MD_INDEX_FLEX_INT: s = drbd_get_capacity(bdev->backing_bdev) ? min_t(sector_t, DRBD_MAX_SECTORS_FLEX, - _drbd_md_first_sector(meta_dev_idx, bdev)) + drbd_md_first_sector(bdev)) : 0; break; case DRBD_MD_INDEX_FLEX_EXT: diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 104b7ce..5621df8 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -722,14 +722,10 @@ static void drbd_md_set_sector_offsets(struct drbd_conf *mdev, { sector_t md_size_sect = 0; unsigned int al_size_sect = MD_32kB_SECT; - int meta_dev_idx; - - rcu_read_lock(); - meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx; bdev->md.md_offset = drbd_md_ss(bdev); - switch (meta_dev_idx) { + switch (bdev->md.meta_dev_idx) { default: /* v07 style fixed size indexed meta data */ bdev->md.md_size_sect = MD_128MB_SECT; @@ -761,7 +757,6 @@ static void drbd_md_set_sector_offsets(struct drbd_conf *mdev, bdev->md.bm_offset = -md_size_sect + MD_4kB_SECT; break; } - rcu_read_unlock(); } /* input size is expected to be in KB */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 00/18] RFC: Non blocking submit for activity log misses
The Issues Since the beginning DRBD was written with the assumption that the write pattern has spacial locality. (This assumption was driven from the fact, that rotating media performs better if you do not send the head too far too often) Backed by this assumption a caller that submits a request that is outside of the current active set, was blocked until the active set was changed. (Changing the active set is a synchronous write operation to the meta-data area on the backing storage = "an AL-update" in DRBD-speak) A second effect was that DRBD's meta-data was located in a very narrow area. When DRBD is used on top of a RAID0 stripe set, this causes all AL-updates to got to the same disk. The Proposed Solution This patch series improves DRBD's behavior. A submitter is no longer blocked in the case of a AL-miss. For this a dedicated submitter worker is introduced (patch 13). In order to better distribute the AL-updates to more disks in a stripe set this patch series also introduces an optional striped layout of the part of the meta-data that holds the AL-updates (patch 4). The Results This of course drastically improves DRBD's performance if the write pattern does not have any spacial locality. E.g. random writes spread out over the whole device. In the test systems we have SSDs with are able to do up to 5 writes per second. The test does random distributed writes over a work set size of 128GiB with IO depths from 1 to 1024. At an IO depth of 64: without this patch we observed ~100 IOPs. With this patches we observed about 2 IOPs. Please find charts of the results here: http://blogs.linbit.com/p/469/843-random-writes-faster/ Lars Ellenberg (18): drbd: cleanup bogus assert message drbd: cleanup ondisk meta data layout calculations and defines drbd: prepare for new striped layout of activity log drbd: use the cached meta_dev_idx drbd: mechanically rename la_size to la_size_sect drbd: read meta data early, base on-disk offsets on super block drbd: Clarify when activity log I/O is delegated to the worker thread drbd: drbd_al_being_io: short circuit to reduce latency drbd: split __drbd_make_request in before and after drbd_al_begin_io drbd: prepare to queue write requests on a submit worker drbd: split drbd_al_begin_io into fastpath, prepare, and commit drbd: split out some helper functions to drbd_al_begin_io drbd: queue writes on submitter thread, unless they pass the activity log fastpath lru_cache: introduce lc_get_cumulative() drbd: consolidate as many updates as possible into one AL transaction drbd: move start io accounting before activity log transaction drbd: try hard to max out the updates per AL transaction drbd: adjust upper limit for activity log extents drivers/block/drbd/drbd_actlog.c | 246 +++- drivers/block/drbd/drbd_bitmap.c | 13 +- drivers/block/drbd/drbd_int.h | 179 +- drivers/block/drbd/drbd_main.c | 243 +-- drivers/block/drbd/drbd_nl.c | 129 --- drivers/block/drbd/drbd_receiver.c |4 +- drivers/block/drbd/drbd_req.c | 166 +--- drivers/block/drbd/drbd_worker.c |5 +- include/linux/drbd_limits.h| 11 +- include/linux/lru_cache.h |1 + lib/lru_cache.c| 55 ++-- 11 files changed, 782 insertions(+), 270 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 03/18] drbd: prepare for new striped layout of activity log
From: Lars Ellenberg Introduce two new on-disk meta data fields: al_stripes and al_stripe_size_4k The intended use case is activity log on RAID 0 or similar. Logically consecutive transactions will advance their on-disk position by al_stripe_size_4k 4kB (transaction sized) blocks. Right now, these are still asserted to be the backward compatible values al_stripes = 1, al_stripe_size_4k = 8 (which amounts to 32kB). Also introduce a caching member for meta_dev_idx in the in-core structure: even though it is initially passed in in the rcu-protected disk_conf structure, it cannot change without a detach/attach cycle. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_actlog.c |6 +-- drivers/block/drbd/drbd_int.h| 46 ++- drivers/block/drbd/drbd_main.c | 77 ++ drivers/block/drbd/drbd_nl.c |5 +-- 4 files changed, 94 insertions(+), 40 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index b230d91..7e7680e 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -353,11 +353,11 @@ static unsigned int rs_extent_to_bm_page(unsigned int rs_enr) static sector_t al_tr_number_to_on_disk_sector(struct drbd_conf *mdev) { - const unsigned int stripes = 1; - const unsigned int stripe_size_4kB = MD_32kB_SECT/MD_4kB_SECT; + const unsigned int stripes = mdev->ldev->md.al_stripes; + const unsigned int stripe_size_4kB = mdev->ldev->md.al_stripe_size_4k; /* transaction number, modulo on-disk ring buffer wrap around */ - unsigned int t = mdev->al_tr_number % (stripe_size_4kB * stripes); + unsigned int t = mdev->al_tr_number % (mdev->ldev->md.al_size_4k); /* ... to aligned 4k on disk block */ t = ((t % stripes) * stripe_size_4kB) + t/stripes; diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 60c89e5..ee19ba2 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -755,6 +755,14 @@ struct drbd_md { s32 al_offset; /* signed relative sector offset to activity log */ s32 bm_offset; /* signed relative sector offset to bitmap */ + + /* cached value of bdev->disk_conf->meta_dev_idx (see below) */ + s32 meta_dev_idx; + + /* see al_tr_number_to_on_disk_sector() */ + u32 al_stripes; + u32 al_stripe_size_4k; + u32 al_size_4k; /* cached product of the above */ }; struct drbd_backing_dev { @@ -1862,38 +1870,24 @@ static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev) } /** - * drbd_md_ss__() - Return the sector number of our meta data super block - * @mdev: DRBD device. + * drbd_md_ss() - Return the sector number of our meta data super block * @bdev: Meta data block device. */ -static inline sector_t drbd_md_ss__(struct drbd_conf *mdev, - struct drbd_backing_dev *bdev) +static inline sector_t drbd_md_ss(struct drbd_backing_dev *bdev) { - int meta_dev_idx; + const int meta_dev_idx = bdev->md.meta_dev_idx; - rcu_read_lock(); - meta_dev_idx = rcu_dereference(bdev->disk_conf)->meta_dev_idx; - rcu_read_unlock(); + if (meta_dev_idx == DRBD_MD_INDEX_FLEX_EXT) + return 0; - switch (meta_dev_idx) { - default: /* external, some index; this is the old fixed size layout */ - return MD_128MB_SECT * meta_dev_idx; - case DRBD_MD_INDEX_INTERNAL: - /* with drbd08, internal meta data is always "flexible" */ - case DRBD_MD_INDEX_FLEX_INT: - if (!bdev->backing_bdev) { - if (__ratelimit(&drbd_ratelimit_state)) { - dev_err(DEV, "bdev->backing_bdev==NULL\n"); - dump_stack(); - } - return 0; - } - /* sizeof(struct md_on_disk_07) == 4k -* position: last 4k aligned block of 4k size */ + /* Since drbd08, internal meta data is always "flexible". +* position: last 4k aligned block of 4k size */ + if (meta_dev_idx == DRBD_MD_INDEX_INTERNAL || + meta_dev_idx == DRBD_MD_INDEX_FLEX_INT) return (drbd_get_capacity(bdev->backing_bdev) & ~7ULL) - 8; - case DRBD_MD_INDEX_FLEX_EXT: - return 0; - } + + /* external, some index; this is the old fixed size layout */ + return MD_128MB_SECT * bdev->md.meta_dev_idx; } static inline void diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 6c4f0ff..b9bfb10 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2853,7 +2853,11 @@ struct meta_data_on_disk { u3
[PATCH 17/18] drbd: try hard to max out the updates per AL transaction
From: Lars Ellenberg There may have been more incoming requests while we where preparing the current transaction. Try to consolidate more updates into this transaction until we make no more progres. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_req.c | 31 +++ 1 file changed, 31 insertions(+) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index d72f2fe..9f7ff1c 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1226,6 +1226,37 @@ void do_submit(struct work_struct *ws) break; wait_event(mdev->al_wait, prepare_al_transaction_nonblock(mdev, &incoming, &pending)); + /* Maybe more was queued, while we prepared the transaction? +* Try to stuff them into this transaction as well. +* Be strictly non-blocking here, no wait_event, we already +* have something to commit. +* Stop if we don't make any more progres. +*/ + for (;;) { + LIST_HEAD(more_pending); + LIST_HEAD(more_incoming); + bool made_progress; + + /* It is ok to look outside the lock, +* it's only an optimization anyways */ + if (list_empty(&mdev->submit.writes)) + break; + + spin_lock(&mdev->submit.lock); + list_splice_tail_init(&mdev->submit.writes, &more_incoming); + spin_unlock(&mdev->submit.lock); + + if (list_empty(&more_incoming)) + break; + + made_progress = prepare_al_transaction_nonblock(mdev, &more_incoming, &more_pending); + + list_splice_tail_init(&more_pending, &pending); + list_splice_tail_init(&more_incoming, &incoming); + + if (!made_progress) + break; + } drbd_al_begin_io_commit(mdev, false); list_for_each_entry_safe(req, tmp, &pending, tl_requests) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 18/18] drbd: adjust upper limit for activity log extents
From: Lars Ellenberg Now that the on-disk activity-log ring buffer size is adjustable, the maximum active set can become larger, and is now limited by the use of 16bit "labels". This increases the maximum working set from 6433 to 65534 extents, each of which covers an area of 4MiB. Which means that if you use the maximum, you'd have to resync more than 250 GiB after an unclean Primary shutdown. With capable backend storage and replication links, this is entirely feasible. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_nl.c | 47 ++ include/linux/drbd_limits.h | 11 +- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index bcf900b..42fda4a 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1141,15 +1141,32 @@ static bool should_set_defaults(struct genl_info *info) return 0 != (flags & DRBD_GENL_F_SET_DEFAULTS); } -static void enforce_disk_conf_limits(struct disk_conf *dc) +static unsigned int drbd_al_extents_max(struct drbd_backing_dev *bdev) { - if (dc->al_extents < DRBD_AL_EXTENTS_MIN) - dc->al_extents = DRBD_AL_EXTENTS_MIN; - if (dc->al_extents > DRBD_AL_EXTENTS_MAX) - dc->al_extents = DRBD_AL_EXTENTS_MAX; + /* This is limited by 16 bit "slot" numbers, +* and by available on-disk context storage. +* +* Also (u16)~0 is special (denotes a "free" extent). +* +* One transaction occupies one 4kB on-disk block, +* we have n such blocks in the on disk ring buffer, +* the "current" transaction may fail (n-1), +* and there is 919 slot numbers context information per transaction. +* +* 72 transaction blocks amounts to more than 2**16 context slots, +* so cap there first. +*/ + const unsigned int max_al_nr = DRBD_AL_EXTENTS_MAX; + const unsigned int sufficient_on_disk = + (max_al_nr + AL_CONTEXT_PER_TRANSACTION -1) + /AL_CONTEXT_PER_TRANSACTION; - if (dc->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX) - dc->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX; + unsigned int al_size_4k = bdev->md.al_size_4k; + + if (al_size_4k > sufficient_on_disk) + return max_al_nr; + + return (al_size_4k - 1) * AL_CONTEXT_PER_TRANSACTION; } int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) @@ -1196,7 +1213,13 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) if (!expect(new_disk_conf->resync_rate >= 1)) new_disk_conf->resync_rate = 1; - enforce_disk_conf_limits(new_disk_conf); + if (new_disk_conf->al_extents < DRBD_AL_EXTENTS_MIN) + new_disk_conf->al_extents = DRBD_AL_EXTENTS_MIN; + if (new_disk_conf->al_extents > drbd_al_extents_max(mdev->ldev)) + new_disk_conf->al_extents = drbd_al_extents_max(mdev->ldev); + + if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX) + new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX; fifo_size = (new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ; if (fifo_size != mdev->rs_plan_s->size) { @@ -1344,7 +1367,8 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) goto fail; } - enforce_disk_conf_limits(new_disk_conf); + if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX) + new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX; new_plan = fifo_alloc((new_disk_conf->c_plan_ahead * 10 * SLEEP_TIME) / HZ); if (!new_plan) { @@ -1419,6 +1443,11 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) if (retcode != NO_ERROR) goto fail; + if (new_disk_conf->al_extents < DRBD_AL_EXTENTS_MIN) + new_disk_conf->al_extents = DRBD_AL_EXTENTS_MIN; + if (new_disk_conf->al_extents > drbd_al_extents_max(nbc)) + new_disk_conf->al_extents = drbd_al_extents_max(nbc); + if (drbd_get_max_capacity(nbc) < new_disk_conf->disk_size) { dev_err(DEV, "max capacity %llu smaller than disk size %llu\n", (unsigned long long) drbd_get_max_capacity(nbc), diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h index 1fa19c5..1fedf2b 100644 --- a/include/linux/drbd_limits.h +++ b/include/linux/drbd_limits.h @@ -126,13 +126,12 @@ #define DRBD_RESYNC_RATE_DEF 250 #define DRBD_RESYNC_RATE_SCALE 'k' /* kilobytes */ - /* less than 7 would hit performance unnecessarily. - * 919 slots context information per transaction, - * 32k a
[PATCH 16/18] drbd: move start io accounting before activity log transaction
From: Lars Ellenberg The IO accounting of the drbd "queue depth" was misleading. We only started IO accounting once we already wrote the activity log. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_req.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index b923d41..d72f2fe 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1056,6 +1056,9 @@ drbd_request_prepare(struct drbd_conf *mdev, struct bio *bio, unsigned long star req->private_bio = NULL; } + /* Update disk stats */ + _drbd_start_io_acct(mdev, req); + if (rw == WRITE && req->private_bio && req->i.size && !test_bit(AL_SUSPENDED, &mdev->flags)) { if (!drbd_al_begin_io_fastpath(mdev, &req->i)) { @@ -1095,9 +1098,6 @@ static void drbd_send_and_submit(struct drbd_conf *mdev, struct drbd_request *re goto out; } - /* Update disk stats */ - _drbd_start_io_acct(mdev, req); - /* We fail READ/READA early, if we can not serve it. * We must do this before req is registered on any lists. * Otherwise, drbd_req_complete() will queue failed READ for retry. */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 14/18] lru_cache: introduce lc_get_cumulative()
From: Lars Ellenberg New helper to be able to consolidate more updates into a single transaction. Without this, we can only grab a single refcount on an updated element while preparing a transaction. lc_get_cumulative - like lc_get; also finds to-be-changed elements @lc: the lru cache to operate on @enr: the label to look up Unlike lc_get this also returns the element for @enr, if it is belonging to a pending transaction, so the return values are like for lc_get(), plus: pointer to an element already on the "to_be_changed" list. In this case, the cache was already marked %LC_DIRTY. Caller needs to make sure that the pending transaction is completed, before proceeding to actually use this element. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- include/linux/lru_cache.h |1 + lib/lru_cache.c | 55 - 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/include/linux/lru_cache.h b/include/linux/lru_cache.h index 4019013..4626228 100644 --- a/include/linux/lru_cache.h +++ b/include/linux/lru_cache.h @@ -256,6 +256,7 @@ extern void lc_destroy(struct lru_cache *lc); extern void lc_set(struct lru_cache *lc, unsigned int enr, int index); extern void lc_del(struct lru_cache *lc, struct lc_element *element); +extern struct lc_element *lc_get_cumulative(struct lru_cache *lc, unsigned int enr); extern struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr); extern struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr); extern struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr); diff --git a/lib/lru_cache.c b/lib/lru_cache.c index d71d894..e8d5003 100644 --- a/lib/lru_cache.c +++ b/lib/lru_cache.c @@ -366,7 +366,13 @@ static int lc_unused_element_available(struct lru_cache *lc) return 0; } -static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, bool may_change) +/* used as internal flags to __lc_get */ +enum { + LC_GET_MAY_CHANGE = 1, + LC_GET_MAY_USE_UNCOMMITTED = 2, +}; + +static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, unsigned int flags) { struct lc_element *e; @@ -381,22 +387,31 @@ static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, bool * this enr is currently being pulled in already, * and will be available once the pending transaction * has been committed. */ - if (e && e->lc_new_number == e->lc_number) { + if (e) { + if (e->lc_new_number != e->lc_number) { + /* It has been found above, but on the "to_be_changed" +* list, not yet committed. Don't pull it in twice, +* wait for the transaction, then try again... +*/ + if (!(flags & LC_GET_MAY_USE_UNCOMMITTED)) + RETURN(NULL); + /* ... unless the caller is aware of the implications, +* probably preparing a cumulative transaction. */ + ++e->refcnt; + ++lc->hits; + RETURN(e); + } + /* else: lc_new_number == lc_number; a real hit. */ ++lc->hits; if (e->refcnt++ == 0) lc->used++; list_move(&e->list, &lc->in_use); /* Not evictable... */ RETURN(e); } + /* e == NULL */ ++lc->misses; - if (!may_change) - RETURN(NULL); - - /* It has been found above, but on the "to_be_changed" list, not yet -* committed. Don't pull it in twice, wait for the transaction, then -* try again */ - if (e) + if (!(flags & LC_GET_MAY_CHANGE)) RETURN(NULL); /* To avoid races with lc_try_lock(), first, mark us dirty @@ -478,7 +493,27 @@ static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, bool */ struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) { - return __lc_get(lc, enr, 1); + return __lc_get(lc, enr, LC_GET_MAY_CHANGE); +} + +/** + * lc_get_cumulative - like lc_get; also finds to-be-changed elements + * @lc: the lru cache to operate on + * @enr: the label to look up + * + * Unlike lc_get this also returns the element for @enr, if it is belonging to + * a pending transaction, so the return values are like for lc_get(), + * plus: + * + * pointer to an element already on the "to_be_changed" list. + * In this case, the cache was already marked %LC_DIRTY. + * + * Caller needs to make sure that the pending transaction is completed, + * before proceeding to actually use this element. + */ +struct lc_element *lc_get_cumulative(struct lru
[PATCH 13/18] drbd: queue writes on submitter thread, unless they pass the activity log fastpath
From: Lars Ellenberg Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_req.c | 20 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 4af709e..43bc1d0 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1020,6 +1020,14 @@ drbd_submit_req_private_bio(struct drbd_request *req) bio_endio(bio, -EIO); } +static void drbd_queue_write(struct drbd_conf *mdev, struct drbd_request *req) +{ + spin_lock(&mdev->submit.lock); + list_add_tail(&req->tl_requests, &mdev->submit.writes); + spin_unlock(&mdev->submit.lock); + queue_work(mdev->submit.wq, &mdev->submit.worker); +} + /* returns the new drbd_request pointer, if the caller is expected to * drbd_send_and_submit() it (to save latency), or NULL if we queued the * request on the submitter thread. @@ -1048,17 +1056,13 @@ drbd_request_prepare(struct drbd_conf *mdev, struct bio *bio, unsigned long star req->private_bio = NULL; } - /* For WRITES going to the local disk, grab a reference on the target -* extent. This waits for any resync activity in the corresponding -* resync extent to finish, and, if necessary, pulls in the target -* extent into the activity log, which involves further disk io because -* of transactional on-disk meta data updates. -* Empty flushes don't need to go into the activity log, they can only -* flush data for pending writes which are already in there. */ if (rw == WRITE && req->private_bio && req->i.size && !test_bit(AL_SUSPENDED, &mdev->flags)) { + if (!drbd_al_begin_io_fastpath(mdev, &req->i)) { + drbd_queue_write(mdev, req); + return NULL; + } req->rq_state |= RQ_IN_ACT_LOG; - drbd_al_begin_io(mdev, &req->i, true); } return req; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 15/18] drbd: consolidate as many updates as possible into one AL transaction
From: Lars Ellenberg Depending on current IO depth, try to consolidate as many updates as possible into one activity log transaction. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_actlog.c | 49 ++ drivers/block/drbd/drbd_int.h|2 ++ drivers/block/drbd/drbd_req.c| 70 ++ 3 files changed, 107 insertions(+), 14 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index ff03f90..6afe173 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -359,6 +359,55 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool dele drbd_al_begin_io_commit(mdev, delegate); } +int drbd_al_begin_io_nonblock(struct drbd_conf *mdev, struct drbd_interval *i) +{ + struct lru_cache *al = mdev->act_log; + /* for bios crossing activity log extent boundaries, +* we may need to activate two extents in one go */ + unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); + unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); + unsigned nr_al_extents; + unsigned available_update_slots; + unsigned enr; + + D_ASSERT(first <= last); + + nr_al_extents = 1 + last - first; /* worst case: all touched extends are cold. */ + available_update_slots = min(al->nr_elements - al->used, + al->max_pending_changes - al->pending_changes); + + /* We want all necessary updates for a given request within the same transaction +* We could first check how many updates are *actually* needed, +* and use that instead of the worst-case nr_al_extents */ + if (available_update_slots < nr_al_extents) + return -EWOULDBLOCK; + + /* Is resync active in this area? */ + for (enr = first; enr <= last; enr++) { + struct lc_element *tmp; + tmp = lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT); + if (unlikely(tmp != NULL)) { + struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); + if (test_bit(BME_NO_WRITES, &bm_ext->flags)) { + if (!test_and_set_bit(BME_PRIORITY, &bm_ext->flags)); + return -EBUSY; + return -EWOULDBLOCK; + } + } + } + + /* Checkout the refcounts. +* Given that we checked for available elements and update slots above, +* this has to be successful. */ + for (enr = first; enr <= last; enr++) { + struct lc_element *al_ext; + al_ext = lc_get_cumulative(mdev->act_log, enr); + if (!al_ext) + dev_info(DEV, "LOGIC BUG for enr=%u\n", enr); + } + return 0; +} + void drbd_al_complete_io(struct drbd_conf *mdev, struct drbd_interval *i) { /* for bios crossing activity log extent boundaries, diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index b7b52dd..f943aac 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1611,6 +1611,8 @@ extern const char *drbd_conn_str(enum drbd_conns s); extern const char *drbd_role_str(enum drbd_role s); /* drbd_actlog.c */ +extern int drbd_al_begin_io_nonblock(struct drbd_conf *mdev, struct drbd_interval *i); +extern void drbd_al_begin_io_commit(struct drbd_conf *mdev, bool delegate); extern bool drbd_al_begin_io_fastpath(struct drbd_conf *mdev, struct drbd_interval *i); extern void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool delegate); extern void drbd_al_complete_io(struct drbd_conf *mdev, struct drbd_interval *i); diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 43bc1d0..b923d41 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1164,32 +1164,74 @@ void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long drbd_send_and_submit(mdev, req); } -void __drbd_make_request_from_worker(struct drbd_conf *mdev, struct drbd_request *req) +static void submit_fast_path(struct drbd_conf *mdev, struct list_head *incoming) { - const int rw = bio_rw(req->master_bio); + struct drbd_request *req, *tmp; + list_for_each_entry_safe(req, tmp, incoming, tl_requests) { + const int rw = bio_data_dir(req->master_bio); - if (rw == WRITE && req->private_bio && req->i.size - && !test_bit(AL_SUSPENDED, &mdev->flags)) { - drbd_al_begin_io(mdev, &req->i, false); - req->rq_state |= RQ_I
[PATCH 11/18] drbd: split drbd_al_begin_io into fastpath, prepare, and commit
From: Lars Ellenberg Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_actlog.c | 104 ++ drivers/block/drbd/drbd_int.h|1 + 2 files changed, 72 insertions(+), 33 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 1d7244d..e4f1231 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -104,7 +104,6 @@ struct update_al_work { int err; }; -static int al_write_transaction(struct drbd_conf *mdev, bool delegate); void *drbd_md_get_buffer(struct drbd_conf *mdev) { @@ -246,30 +245,37 @@ static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr) return al_ext; } -/* - * @delegate: delegate activity log I/O to the worker thread - */ -void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool delegate) +bool drbd_al_begin_io_fastpath(struct drbd_conf *mdev, struct drbd_interval *i) { /* for bios crossing activity log extent boundaries, * we may need to activate two extents in one go */ unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); - unsigned enr; - bool need_transaction = false; - bool locked = false; + bool fastpath_ok = true; - /* When called through generic_make_request(), we must delegate -* activity log I/O to the worker thread: a further request -* submitted via generic_make_request() within the same task -* would be queued on current->bio_list, and would only start -* after this function returns (see generic_make_request()). -* -* However, if we *are* the worker, we must not delegate to ourselves. -*/ + D_ASSERT((unsigned)(last - first) <= 1); + D_ASSERT(atomic_read(&mdev->local_cnt) > 0); + + /* FIXME figure out a fast path for bios crossing AL extent boundaries */ + if (first != last) + return false; + + spin_lock_irq(&mdev->al_lock); + fastpath_ok = + lc_find(mdev->resync, first/AL_EXT_PER_BM_SECT) == NULL && + lc_try_get(mdev->act_log, first) != NULL; + spin_unlock_irq(&mdev->al_lock); + return fastpath_ok; +} - if (delegate) - BUG_ON(current == mdev->tconn->worker.task); +bool drbd_al_begin_io_prepare(struct drbd_conf *mdev, struct drbd_interval *i) +{ + /* for bios crossing activity log extent boundaries, +* we may need to activate two extents in one go */ + unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); + unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); + unsigned enr; + bool need_transaction = false; D_ASSERT(first <= last); D_ASSERT(atomic_read(&mdev->local_cnt) > 0); @@ -280,11 +286,28 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool dele if (al_ext->lc_number != enr) need_transaction = true; } + return need_transaction; +} - /* If *this* request was to an already active extent, -* we're done, even if there are pending changes. */ - if (!need_transaction) - return; +static int al_write_transaction(struct drbd_conf *mdev, bool delegate); + +/* When called through generic_make_request(), we must delegate + * activity log I/O to the worker thread: a further request + * submitted via generic_make_request() within the same task + * would be queued on current->bio_list, and would only start + * after this function returns (see generic_make_request()). + * + * However, if we *are* the worker, we must not delegate to ourselves. + */ + +/* + * @delegate: delegate activity log I/O to the worker thread + */ +void drbd_al_begin_io_commit(struct drbd_conf *mdev, bool delegate) +{ + bool locked = false; + + BUG_ON(delegate && current == mdev->tconn->worker.task); /* Serialize multiple transactions. * This uses test_and_set_bit, memory barrier is implicit. @@ -303,11 +326,8 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool dele write_al_updates = rcu_dereference(mdev->ldev->disk_conf)->al_updates; rcu_read_unlock(); - if (write_al_updates) { + if (write_al_updates) al_write_transaction(mdev, delegate); - mdev->al_writ_cnt++; - } - spin_lock_irq(&mdev->al_lock); /* FIXME
[PATCH 12/18] drbd: split out some helper functions to drbd_al_begin_io
From: Lars Ellenberg To make the code easier to follow, use an explicit find_active_resync_extent(), and add a "nonblock" parameter to _al_get(). Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_actlog.c | 49 ++ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index e4f1231..ff03f90 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -222,25 +222,37 @@ int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, return err; } -static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr) +static struct bm_extent *find_active_resync_extent(struct drbd_conf *mdev, unsigned int enr) { - struct lc_element *al_ext; struct lc_element *tmp; - int wake; - - spin_lock_irq(&mdev->al_lock); tmp = lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT); if (unlikely(tmp != NULL)) { struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); - if (test_bit(BME_NO_WRITES, &bm_ext->flags)) { - wake = !test_and_set_bit(BME_PRIORITY, &bm_ext->flags); - spin_unlock_irq(&mdev->al_lock); - if (wake) - wake_up(&mdev->al_wait); - return NULL; - } + if (test_bit(BME_NO_WRITES, &bm_ext->flags)) + return bm_ext; } - al_ext = lc_get(mdev->act_log, enr); + return NULL; +} + +static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr, bool nonblock) +{ + struct lc_element *al_ext; + struct bm_extent *bm_ext; + int wake; + + spin_lock_irq(&mdev->al_lock); + bm_ext = find_active_resync_extent(mdev, enr); + if (bm_ext) { + wake = !test_and_set_bit(BME_PRIORITY, &bm_ext->flags); + spin_unlock_irq(&mdev->al_lock); + if (wake) + wake_up(&mdev->al_wait); + return NULL; + } + if (nonblock) + al_ext = lc_try_get(mdev->act_log, enr); + else + al_ext = lc_get(mdev->act_log, enr); spin_unlock_irq(&mdev->al_lock); return al_ext; } @@ -251,7 +263,6 @@ bool drbd_al_begin_io_fastpath(struct drbd_conf *mdev, struct drbd_interval *i) * we may need to activate two extents in one go */ unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); - bool fastpath_ok = true; D_ASSERT((unsigned)(last - first) <= 1); D_ASSERT(atomic_read(&mdev->local_cnt) > 0); @@ -260,12 +271,7 @@ bool drbd_al_begin_io_fastpath(struct drbd_conf *mdev, struct drbd_interval *i) if (first != last) return false; - spin_lock_irq(&mdev->al_lock); - fastpath_ok = - lc_find(mdev->resync, first/AL_EXT_PER_BM_SECT) == NULL && - lc_try_get(mdev->act_log, first) != NULL; - spin_unlock_irq(&mdev->al_lock); - return fastpath_ok; + return _al_get(mdev, first, true); } bool drbd_al_begin_io_prepare(struct drbd_conf *mdev, struct drbd_interval *i) @@ -282,7 +288,8 @@ bool drbd_al_begin_io_prepare(struct drbd_conf *mdev, struct drbd_interval *i) for (enr = first; enr <= last; enr++) { struct lc_element *al_ext; - wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)) != NULL); + wait_event(mdev->al_wait, + (al_ext = _al_get(mdev, enr, false)) != NULL); if (al_ext->lc_number != enr) need_transaction = true; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 09/18] drbd: split __drbd_make_request in before and after drbd_al_begin_io
From: Lars Ellenberg This is in preparation to be able to defer requests that need to wait for an activity log transaction to a submitter workqueue. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_req.c | 40 ++-- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 7d1ff1a..96d5968 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -34,14 +34,14 @@ static bool drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int size); /* Update disk stats at start of I/O request */ -static void _drbd_start_io_acct(struct drbd_conf *mdev, struct drbd_request *req, struct bio *bio) +static void _drbd_start_io_acct(struct drbd_conf *mdev, struct drbd_request *req) { - const int rw = bio_data_dir(bio); + const int rw = bio_data_dir(req->master_bio); int cpu; cpu = part_stat_lock(); part_round_stats(cpu, &mdev->vdisk->part0); part_stat_inc(cpu, &mdev->vdisk->part0, ios[rw]); - part_stat_add(cpu, &mdev->vdisk->part0, sectors[rw], bio_sectors(bio)); + part_stat_add(cpu, &mdev->vdisk->part0, sectors[rw], req->i.size >> 9); (void) cpu; /* The macro invocations above want the cpu argument, I do not like the compiler warning about cpu only assigned but never used... */ part_inc_in_flight(&mdev->vdisk->part0, rw); @@ -1020,12 +1020,16 @@ drbd_submit_req_private_bio(struct drbd_request *req) bio_endio(bio, -EIO); } -void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) +/* returns the new drbd_request pointer, if the caller is expected to + * drbd_send_and_submit() it (to save latency), or NULL if we queued the + * request on the submitter thread. + * Returns ERR_PTR(-ENOMEM) if we cannot allocate a drbd_request. + */ +struct drbd_request * +drbd_request_prepare(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) { - const int rw = bio_rw(bio); - struct bio_and_error m = { NULL, }; + const int rw = bio_data_dir(bio); struct drbd_request *req; - bool no_remote = false; /* allocate outside of all locks; */ req = drbd_req_new(mdev, bio); @@ -1035,7 +1039,7 @@ void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long * if user cannot handle io errors, that's not our business. */ dev_err(DEV, "could not kmalloc() req\n"); bio_endio(bio, -ENOMEM); - return; + return ERR_PTR(-ENOMEM); } req->start_time = start_time; @@ -1057,6 +1061,15 @@ void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long drbd_al_begin_io(mdev, &req->i, true); } + return req; +} + +static void drbd_send_and_submit(struct drbd_conf *mdev, struct drbd_request *req) +{ + const int rw = bio_rw(req->master_bio); + struct bio_and_error m = { NULL, }; + bool no_remote = false; + spin_lock_irq(&mdev->tconn->req_lock); if (rw == WRITE) { /* This may temporarily give up the req_lock, @@ -1079,7 +1092,7 @@ void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long } /* Update disk stats */ - _drbd_start_io_acct(mdev, req, bio); + _drbd_start_io_acct(mdev, req); /* We fail READ/READA early, if we can not serve it. * We must do this before req is registered on any lists. @@ -1137,7 +1150,14 @@ out: if (m.bio) complete_master_bio(mdev, &m); - return; +} + +void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) +{ + struct drbd_request *req = drbd_request_prepare(mdev, bio, start_time); + if (IS_ERR_OR_NULL(req)) + return; + drbd_send_and_submit(mdev, req); } void drbd_make_request(struct request_queue *q, struct bio *bio) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 10/18] drbd: prepare to queue write requests on a submit worker
From: Lars Ellenberg Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 13 + drivers/block/drbd/drbd_main.c | 25 - drivers/block/drbd/drbd_nl.c |1 + drivers/block/drbd/drbd_req.c | 29 + 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 453fccf..a6b71b6 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -894,6 +894,14 @@ struct drbd_tconn {/* is a resource from the config file */ } send; }; +struct submit_worker { + struct workqueue_struct *wq; + struct work_struct worker; + + spinlock_t lock; + struct list_head writes; +}; + struct drbd_conf { struct drbd_tconn *tconn; int vnr;/* volume number within the connection */ @@ -1034,6 +1042,10 @@ struct drbd_conf { atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */ unsigned int peer_max_bio_size; unsigned int local_max_bio_size; + + /* any requests that would block in drbd_make_request() +* are deferred to this single-threaded work queue */ + struct submit_worker submit; }; static inline struct drbd_conf *minor_to_mdev(unsigned int minor) @@ -1440,6 +1452,7 @@ extern void conn_free_crypto(struct drbd_tconn *tconn); extern int proc_details; /* drbd_req */ +extern void do_submit(struct work_struct *ws); extern void __drbd_make_request(struct drbd_conf *, struct bio *, unsigned long); extern void drbd_make_request(struct request_queue *q, struct bio *bio); extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 3d212b9..c84226e 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -45,7 +45,7 @@ #include #include #include - +#include #define __KERNEL_SYSCALLS__ #include #include @@ -2300,6 +2300,7 @@ static void drbd_cleanup(void) idr_for_each_entry(&minors, mdev, i) { idr_remove(&minors, mdev_to_minor(mdev)); idr_remove(&mdev->tconn->volumes, mdev->vnr); + destroy_workqueue(mdev->submit.wq); del_gendisk(mdev->vdisk); /* synchronize_rcu(); No other threads running at this point */ kref_put(&mdev->kref, &drbd_minor_destroy); @@ -2589,6 +2590,21 @@ void conn_destroy(struct kref *kref) kfree(tconn); } +int init_submitter(struct drbd_conf *mdev) +{ + /* opencoded create_singlethread_workqueue(), +* to be able to say "drbd%d", ..., minor */ + mdev->submit.wq = alloc_workqueue("drbd%u_submit", + WQ_UNBOUND | WQ_MEM_RECLAIM, 1, mdev->minor); + if (!mdev->submit.wq) + return -ENOMEM; + + INIT_WORK(&mdev->submit.worker, do_submit); + spin_lock_init(&mdev->submit.lock); + INIT_LIST_HEAD(&mdev->submit.writes); + return 0; +} + enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr) { struct drbd_conf *mdev; @@ -2679,6 +2695,13 @@ enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, drbd_msg_put_info("requested volume exists already"); goto out_idr_remove_vol; } + + if (init_submitter(mdev)) { + err = ERR_NOMEM; + drbd_msg_put_info("unable to create submit workqueue"); + goto out_idr_remove_vol; + } + add_disk(disk); kref_init(&mdev->kref); /* one ref for both idrs and the the add_disk */ diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 974ea47..bcf900b 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -3173,6 +3173,7 @@ static enum drbd_ret_code adm_delete_minor(struct drbd_conf *mdev) CS_VERBOSE + CS_WAIT_COMPLETE); idr_remove(&mdev->tconn->volumes, mdev->vnr); idr_remove(&minors, mdev_to_minor(mdev)); + destroy_workqueue(mdev->submit.wq); del_gendisk(mdev->vdisk); synchronize_rcu(); kref_put(&mdev->kref, &drbd_minor_destroy); diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 96d5968..4af709e 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1160,6 +1160,35 @@ void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long drbd_send_and_submit(mdev, req); } +void __drbd_make_request_from_worker(struct drbd_c
[PATCH 07/18] drbd: Clarify when activity log I/O is delegated to the worker thread
From: Lars Ellenberg Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_actlog.c | 49 drivers/block/drbd/drbd_int.h |2 +- drivers/block/drbd/drbd_receiver.c |2 +- drivers/block/drbd/drbd_req.c |2 +- drivers/block/drbd/drbd_worker.c |2 +- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index c79625a..82199d9 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -104,7 +104,7 @@ struct update_al_work { int err; }; -static int al_write_transaction(struct drbd_conf *mdev); +static int al_write_transaction(struct drbd_conf *mdev, bool delegate); void *drbd_md_get_buffer(struct drbd_conf *mdev) { @@ -246,7 +246,10 @@ static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr) return al_ext; } -void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i) +/* + * @delegate: delegate activity log I/O to the worker thread + */ +void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool delegate) { /* for bios crossing activity log extent boundaries, * we may need to activate two extents in one go */ @@ -255,6 +258,17 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i) unsigned enr; bool locked = false; + /* When called through generic_make_request(), we must delegate +* activity log I/O to the worker thread: a further request +* submitted via generic_make_request() within the same task +* would be queued on current->bio_list, and would only start +* after this function returns (see generic_make_request()). +* +* However, if we *are* the worker, we must not delegate to ourselves. +*/ + + if (delegate) + BUG_ON(current == mdev->tconn->worker.task); D_ASSERT(first <= last); D_ASSERT(atomic_read(&mdev->local_cnt) > 0); @@ -270,13 +284,6 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i) (locked = lc_try_lock_for_transaction(mdev->act_log))); if (locked) { - /* drbd_al_write_transaction(mdev,al_ext,enr); -* recurses into generic_make_request(), which -* disallows recursion, bios being serialized on the -* current->bio_tail list now. -* we have to delegate updates to the activity log -* to the worker thread. */ - /* Double check: it may have been committed by someone else, * while we have been waiting for the lock. */ if (mdev->act_log->pending_changes) { @@ -287,7 +294,7 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i) rcu_read_unlock(); if (write_al_updates) { - al_write_transaction(mdev); + al_write_transaction(mdev, delegate); mdev->al_writ_cnt++; } @@ -495,20 +502,18 @@ static int w_al_write_transaction(struct drbd_work *w, int unused) /* Calls from worker context (see w_restart_disk_io()) need to write the transaction directly. Others came through generic_make_request(), those need to delegate it to the worker. */ -static int al_write_transaction(struct drbd_conf *mdev) +static int al_write_transaction(struct drbd_conf *mdev, bool delegate) { - struct update_al_work al_work; - - if (current == mdev->tconn->worker.task) + if (delegate) { + struct update_al_work al_work; + init_completion(&al_work.event); + al_work.w.cb = w_al_write_transaction; + al_work.w.mdev = mdev; + drbd_queue_work_front(&mdev->tconn->sender_work, &al_work.w); + wait_for_completion(&al_work.event); + return al_work.err; + } else return _al_write_transaction(mdev); - - init_completion(&al_work.event); - al_work.w.cb = w_al_write_transaction; - al_work.w.mdev = mdev; - drbd_queue_work_front(&mdev->tconn->sender_work, &al_work.w); - wait_for_completion(&al_work.event); - - return al_work.err; } static int _try_lc_del(struct drbd_conf *mdev, struct lc_element *al_ext) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 6eecdec..453fccf 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1598,7 +1598,7 @@ extern const char *drbd_conn_str(enum drbd_conns s); extern const char *drbd_role_str(enum drbd_role s); /* drbd_actlog.c */ -extern void drbd_al_begin_io(struct dr
[PATCH 08/18] drbd: drbd_al_being_io: short circuit to reduce latency
From: Lars Ellenberg A request hitting an already "hot" extent should proceed right away, even if some other requests need to wait for pending transactions. Without that short-circuit, several simultaneous make_request contexts race for committing the transaction, possibly penalizing the innocent. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_actlog.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 82199d9..1d7244d 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -256,6 +256,7 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool dele unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); unsigned enr; + bool need_transaction = false; bool locked = false; /* When called through generic_make_request(), we must delegate @@ -273,8 +274,17 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool dele D_ASSERT(first <= last); D_ASSERT(atomic_read(&mdev->local_cnt) > 0); - for (enr = first; enr <= last; enr++) - wait_event(mdev->al_wait, _al_get(mdev, enr) != NULL); + for (enr = first; enr <= last; enr++) { + struct lc_element *al_ext; + wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)) != NULL); + if (al_ext->lc_number != enr) + need_transaction = true; + } + + /* If *this* request was to an already active extent, +* we're done, even if there are pending changes. */ + if (!need_transaction) + return; /* Serialize multiple transactions. * This uses test_and_set_bit, memory barrier is implicit. -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 06/18] drbd: read meta data early, base on-disk offsets on super block
From: Lars Ellenberg We used to calculate all on-disk meta data offsets, and then compare the stored offsets, basically treating them as magic numbers. Now with the activity log striping, the activity log size is no longer fixed. We need to first read the super block, then base the activity log and bitmap offsets on the stored offsets/al stripe settings. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_actlog.c | 11 +++- drivers/block/drbd/drbd_main.c | 131 +++--- drivers/block/drbd/drbd_nl.c | 15 ++--- drivers/block/drbd/drbd_worker.c |3 +- 4 files changed, 123 insertions(+), 37 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 7e7680e..c79625a 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -168,7 +168,11 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, bio->bi_end_io = drbd_md_io_complete; bio->bi_rw = rw; - if (!get_ldev_if_state(mdev, D_ATTACHING)) { /* Corresponding put_ldev in drbd_md_io_complete() */ + if (!(rw & WRITE) && mdev->state.disk == D_DISKLESS && mdev->ldev == NULL) + /* special case, drbd_md_read() during drbd_adm_attach(): no get_ldev */ + ; + else if (!get_ldev_if_state(mdev, D_ATTACHING)) { + /* Corresponding put_ldev in drbd_md_io_complete() */ dev_err(DEV, "ASSERT FAILED: get_ldev_if_state() == 1 in _drbd_md_sync_page_io()\n"); err = -ENODEV; goto out; @@ -199,9 +203,10 @@ int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, BUG_ON(!bdev->md_bdev); - dev_dbg(DEV, "meta_data io: %s [%d]:%s(,%llus,%s)\n", + dev_dbg(DEV, "meta_data io: %s [%d]:%s(,%llus,%s) %pS\n", current->comm, current->pid, __func__, -(unsigned long long)sector, (rw & WRITE) ? "WRITE" : "READ"); +(unsigned long long)sector, (rw & WRITE) ? "WRITE" : "READ", +(void*)_RET_IP_ ); if (sector < drbd_md_first_sector(bdev) || sector + 7 > drbd_md_last_sector(bdev)) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index d8bbb41..3d212b9 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2971,6 +2971,86 @@ err: return -EINVAL; } +static int check_offsets_and_sizes(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) +{ + sector_t capacity = drbd_get_capacity(bdev->md_bdev); + struct drbd_md *in_core = &bdev->md; + s32 on_disk_al_sect; + s32 on_disk_bm_sect; + + /* The on-disk size of the activity log, calculated from offsets, and +* the size of the activity log calculated from the stripe settings, +* should match. +* Though we could relax this a bit: it is ok, if the striped activity log +* fits in the available on-disk activity log size. +* Right now, that would break how resize is implemented. +* TODO: make drbd_determine_dev_size() (and the drbdmeta tool) aware +* of possible unused padding space in the on disk layout. */ + if (in_core->al_offset < 0) { + if (in_core->bm_offset > in_core->al_offset) + goto err; + on_disk_al_sect = -in_core->al_offset; + on_disk_bm_sect = in_core->al_offset - in_core->bm_offset; + } else { + if (in_core->al_offset != MD_4kB_SECT) + goto err; + if (in_core->bm_offset < in_core->al_offset + in_core->al_size_4k * MD_4kB_SECT) + goto err; + + on_disk_al_sect = in_core->bm_offset - MD_4kB_SECT; + on_disk_bm_sect = in_core->md_size_sect - in_core->bm_offset; + } + + /* old fixed size meta data is exactly that: fixed. */ + if (in_core->meta_dev_idx >= 0) { + if (in_core->md_size_sect != MD_128MB_SECT + || in_core->al_offset != MD_4kB_SECT + || in_core->bm_offset != MD_4kB_SECT + MD_32kB_SECT + || in_core->al_stripes != 1 + || in_core->al_stripe_size_4k != MD_32kB_SECT/8) + goto err; + } + + if (capacity < in_core->md_size_sect) + goto err; + if (capacity - in_core->md_size_sect < drbd_md_first_sector(bdev)) + goto err; + + /* should be aligned, and at least 32k */ + if ((on_disk_al_sect & 7) || (on_disk_al_sect < MD_32kB_SECT)) + goto err; + + /* should fit (for now: exactly) into the available on-disk space;
[PATCH 05/18] drbd: mechanically rename la_size to la_size_sect
From: Lars Ellenberg Make it obvious that this value is in units of 512 Byte sectors. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_main.c |6 +++--- drivers/block/drbd/drbd_nl.c | 16 drivers/block/drbd/drbd_receiver.c |2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index b9bfb10..d8bbb41 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2839,7 +2839,7 @@ void conn_md_sync(struct drbd_tconn *tconn) /* aligned 4kByte */ struct meta_data_on_disk { - u64 la_size; /* last agreed size. */ + u64 la_size_sect; /* last agreed size. */ u64 uuid[UI_SIZE]; /* UUIDs. */ u64 device_uuid; u64 reserved_u64_1; @@ -2890,7 +2890,7 @@ void drbd_md_sync(struct drbd_conf *mdev) memset(buffer, 0, sizeof(*buffer)); - buffer->la_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev)); + buffer->la_size_sect = cpu_to_be64(drbd_get_capacity(mdev->this_bdev)); for (i = UI_CURRENT; i < UI_SIZE; i++) buffer->uuid[i] = cpu_to_be64(mdev->ldev->md.uuid[i]); buffer->flags = cpu_to_be32(mdev->ldev->md.flags); @@ -3052,7 +3052,7 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) rv = NO_ERROR; - bdev->md.la_size_sect = be64_to_cpu(buffer->la_size); + bdev->md.la_size_sect = be64_to_cpu(buffer->la_size_sect); for (i = UI_CURRENT; i < UI_SIZE; i++) bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]); bdev->md.flags = be32_to_cpu(buffer->flags); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 5621df8..d5211b0 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -819,7 +819,7 @@ void drbd_resume_io(struct drbd_conf *mdev) enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local) { sector_t prev_first_sect, prev_size; /* previous meta location */ - sector_t la_size, u_size; + sector_t la_size_sect, u_size; sector_t size; char ppb[10]; @@ -842,7 +842,7 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds prev_first_sect = drbd_md_first_sector(mdev->ldev); prev_size = mdev->ldev->md.md_size_sect; - la_size = mdev->ldev->md.la_size_sect; + la_size_sect = mdev->ldev->md.la_size_sect; /* TODO: should only be some assert here, not (re)init... */ drbd_md_set_sector_offsets(mdev, mdev->ldev); @@ -878,7 +878,7 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds if (rv == dev_size_error) goto out; - la_size_changed = (la_size != mdev->ldev->md.la_size_sect); + la_size_changed = (la_size_sect != mdev->ldev->md.la_size_sect); md_moved = prev_first_sect != drbd_md_first_sector(mdev->ldev) || prev_size != mdev->ldev->md.md_size_sect; @@ -900,9 +900,9 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds drbd_md_mark_dirty(mdev); } - if (size > la_size) + if (size > la_size_sect) rv = grew; - if (size < la_size) + if (size < la_size_sect) rv = shrunk; out: lc_unlock(mdev->act_log); @@ -917,7 +917,7 @@ drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, sector_t u_size, int assume_peer_has_space) { sector_t p_size = mdev->p_size; /* partner's disk size. */ - sector_t la_size = bdev->md.la_size_sect; /* last agreed size. */ + sector_t la_size_sect = bdev->md.la_size_sect; /* last agreed size. */ sector_t m_size; /* my size */ sector_t size = 0; @@ -931,8 +931,8 @@ drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, if (p_size && m_size) { size = min_t(sector_t, p_size, m_size); } else { - if (la_size) { - size = la_size; + if (la_size_sect) { + size = la_size_sect; if (m_size && m_size < size) size = m_size; if (p_size && p_size < size) diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index a9eccfc..8172a2c 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -3992,7 +3992,7 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi) clear_bit(DISCARD_MY_DATA,
[PATCH 02/18] drbd: cleanup ondisk meta data layout calculations and defines
From: Lars Ellenberg Add a comment about our meta data layout variants, and rename a few defines (e.g. MD_RESERVED_SECT -> MD_128MB_SECT) to make it clear that they are short hand for fixed constants, and not arbitrarily to be redefined as one may see fit. Properly pad struct meta_data_on_disk to 4kB, and initialize to zero not only the first 512 Byte, but all of it in drbd_md_sync(). Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_actlog.c | 28 ++--- drivers/block/drbd/drbd_bitmap.c | 13 +- drivers/block/drbd/drbd_int.h| 86 ++ drivers/block/drbd/drbd_main.c | 11 +++-- drivers/block/drbd/drbd_nl.c | 42 ++- 5 files changed, 123 insertions(+), 57 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 92510f8..b230d91 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -209,7 +209,8 @@ int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, current->comm, current->pid, __func__, (unsigned long long)sector, (rw & WRITE) ? "WRITE" : "READ"); - err = _drbd_md_sync_page_io(mdev, bdev, iop, sector, rw, MD_BLOCK_SIZE); + /* we do all our meta data IO in aligned 4k blocks. */ + err = _drbd_md_sync_page_io(mdev, bdev, iop, sector, rw, 4096); if (err) { dev_err(DEV, "drbd_md_sync_page_io(,%llus,%s) failed with error %d\n", (unsigned long long)sector, (rw & WRITE) ? "WRITE" : "READ", err); @@ -350,6 +351,24 @@ static unsigned int rs_extent_to_bm_page(unsigned int rs_enr) (BM_EXT_SHIFT - BM_BLOCK_SHIFT)); } +static sector_t al_tr_number_to_on_disk_sector(struct drbd_conf *mdev) +{ + const unsigned int stripes = 1; + const unsigned int stripe_size_4kB = MD_32kB_SECT/MD_4kB_SECT; + + /* transaction number, modulo on-disk ring buffer wrap around */ + unsigned int t = mdev->al_tr_number % (stripe_size_4kB * stripes); + + /* ... to aligned 4k on disk block */ + t = ((t % stripes) * stripe_size_4kB) + t/stripes; + + /* ... to 512 byte sector in activity log */ + t *= 8; + + /* ... plus offset to the on disk position */ + return mdev->ldev->md.md_offset + mdev->ldev->md.al_offset + t; +} + static int _al_write_transaction(struct drbd_conf *mdev) { @@ -432,13 +451,12 @@ _al_write_transaction(struct drbd_conf *mdev) if (mdev->al_tr_cycle >= mdev->act_log->nr_elements) mdev->al_tr_cycle = 0; - sector = mdev->ldev->md.md_offset - + mdev->ldev->md.al_offset - + mdev->al_tr_pos * (MD_BLOCK_SIZE>>9); + sector = al_tr_number_to_on_disk_sector(mdev); crc = crc32c(0, buffer, 4096); buffer->crc32c = cpu_to_be32(crc); + /* normal execution path goes through all three branches */ if (drbd_bm_write_hinted(mdev)) err = -EIO; /* drbd_chk_io_error done already */ @@ -446,8 +464,6 @@ _al_write_transaction(struct drbd_conf *mdev) err = -EIO; drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR); } else { - /* advance ringbuffer position and transaction counter */ - mdev->al_tr_pos = (mdev->al_tr_pos + 1) % (MD_AL_SECTORS*512/MD_BLOCK_SIZE); mdev->al_tr_number++; } diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index 8dc2950..64fbb83 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -612,6 +612,17 @@ static void bm_memset(struct drbd_bitmap *b, size_t offset, int c, size_t len) } } +/* For the layout, see comment above drbd_md_set_sector_offsets(). */ +static u64 drbd_md_on_disk_bits(struct drbd_backing_dev *ldev) +{ + u64 bitmap_sectors; + if (ldev->md.al_offset == 8) + bitmap_sectors = ldev->md.md_size_sect - ldev->md.bm_offset; + else + bitmap_sectors = ldev->md.al_offset - ldev->md.bm_offset; + return bitmap_sectors << (9 + 3); +} + /* * make sure the bitmap has enough room for the attached storage, * if necessary, resize. @@ -668,7 +679,7 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) words = ALIGN(bits, 64) >> LN2_BPL; if (get_ldev(mdev)) { - u64 bits_on_disk = ((u64)mdev->ldev->md.md_size_sect-MD_BM_OFFSET) << 12; + u64 bits_on_disk = drbd_md_on_disk_bits(mdev->ldev); put_ldev(mdev); if (bits > bits_on_disk) { dev_info(DEV, "bits =
[PATCH 01/18] drbd: cleanup bogus assert message
From: Lars Ellenberg This fixes ASSERT( mdev->state.disk == D_FAILED ) in drivers/block/drbd/drbd_main.c When we detach from local disk, we let the local refcount hit zero twice. First, we transition to D_FAILED, so we won't give out new references to incoming requests; we still may give out *internal* references, though. Once the refcount hits zero [1] while in D_FAILED, we queue a transition to D_DISKLESS to our worker. We need to queue it, because we may be in atomic context when putting the reference. Once the transition to D_DISKLESS actually happened [2] from worker context, we don't give out new internal references either. Between hitting zero the first time [1] and actually transition to D_DISKLESS [2], there may be a few very short lived internal get/put, so we may hit zero more than once while being in D_FAILED, or even see a race where a an internal get_ldev() happened while D_FAILED, but the corresponding put_ldev() happens just after the transition to D_DISKLESS. That's why we have the additional test_and_set_bit(GO_DISKLESS,); and that's why the assert was placed wrong. Since there was exactly one code path left to drbd_go_diskless(), and that checks already for D_FAILED, drop that assert, and fold in the drbd_queue_work(). Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h |7 --- drivers/block/drbd/drbd_main.c |7 --- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 6b51afa..db504d0 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1148,7 +1148,6 @@ extern int drbd_bitmap_io_from_worker(struct drbd_conf *mdev, char *why, enum bm_flag flags); extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); -extern void drbd_go_diskless(struct drbd_conf *mdev); extern void drbd_ldev_destroy(struct drbd_conf *mdev); /* Meta data layout @@ -2053,9 +2052,11 @@ static inline void put_ldev(struct drbd_conf *mdev) if (mdev->state.disk == D_DISKLESS) /* even internal references gone, safe to destroy */ drbd_ldev_destroy(mdev); - if (mdev->state.disk == D_FAILED) + if (mdev->state.disk == D_FAILED) { /* all application IO references gone. */ - drbd_go_diskless(mdev); + if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) + drbd_queue_work(&mdev->tconn->sender_work, &mdev->go_diskless); + } wake_up(&mdev->misc_wait); } } diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 8c13eeb..6224963 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3255,13 +3255,6 @@ static int w_go_diskless(struct drbd_work *w, int unused) return 0; } -void drbd_go_diskless(struct drbd_conf *mdev) -{ - D_ASSERT(mdev->state.disk == D_FAILED); - if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) - drbd_queue_work(&mdev->tconn->sender_work, &mdev->go_diskless); -} - /** * drbd_queue_bitmap_io() - Queues an IO operation on the whole bitmap * @mdev: DRBD device. -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v9 RESEND 0/4] Add generic driver for on-chip SRAM
Hi, last time I posted was a bit close to the merge window, so I'm reposting now. Greg, Arnd, could you take the first two patches? These patches add support to configure on-chip SRAM via device-tree node or platform data and to obtain the resulting genalloc pool from the struct device pointer or a phandle pointing at the device tree node. This allows drivers to allocate SRAM with the genalloc API without hard-coding the genalloc pool pointer. The on-chip SRAM on i.MX53 and i.MX6q can be registered via device tree and changed to use the simple generic SRAM driver: ocram: ocram@0090 { compatible = "fsl,imx-ocram", "mmio-sram"; reg = <0x0090 0x3f000>; }; A driver that needs to allocate SRAM buffers, like the video processing unit on i.MX53, can retrieve the genalloc pool from a phandle in the device tree using of_get_named_gen_pool(node, "iram", 0) from patch 1: vpu@63ff4000 { /* ... */ iram = <&ocram>; }; Changes since v8: - The sram driver now matches against the "mmio-sram" compatible string. - Removed a whitespace error in the device tree binding documentation. regards Philipp --- Documentation/devicetree/bindings/media/coda.txt | 30 ++ Documentation/devicetree/bindings/misc/sram.txt | 16 +++ arch/arm/boot/dts/imx53.dtsi |5 + arch/arm/boot/dts/imx6q.dtsi |6 ++ drivers/media/platform/Kconfig |1 - drivers/media/platform/coda.c| 45 +--- drivers/misc/Kconfig |9 ++ drivers/misc/Makefile|1 + drivers/misc/sram.c | 121 ++ include/linux/genalloc.h | 15 +++ include/linux/platform_data/coda.h | 18 lib/genalloc.c | 81 +++ 12 files changed, 333 insertions(+), 15 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v9 RESEND 4/4] ARM: dts: add sram for imx53 and imx6q
Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo Acked-by: Grant Likely --- Changes since v8: - Changed device tree compatible string to "mmio-sram" --- arch/arm/boot/dts/imx53.dtsi |5 + arch/arm/boot/dts/imx6q.dtsi |6 ++ 2 files changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index edc3f1e..69d0680 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -664,5 +664,10 @@ status = "disabled"; }; }; + + ocram: ocram@f800 { + compatible = "fsl,imx-ocram", "mmio-sram"; + reg = <0xf800 0x2>; + }; }; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index ff1205e..73302db 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -124,6 +124,12 @@ status = "disabled"; }; + ocram: ocram@0090 { + compatible = "fsl,imx-ocram", "mmio-sram"; + reg = <0x0090 0x3f000>; + clocks = <&clks 142>; + }; + timer@00a00600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x00a00600 0x20>; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v9 RESEND 1/4] genalloc: add devres support, allow to find a managed pool by device
This patch adds three exported functions to lib/genalloc.c: devm_gen_pool_create, dev_get_gen_pool, and of_get_named_gen_pool. devm_gen_pool_create is a managed version of gen_pool_create that keeps track of the pool via devres and allows the management code to automatically destroy it after device removal. dev_get_gen_pool retrieves the gen_pool for a given device, if it was created with devm_gen_pool_create, using devres_find. of_get_named_gen_pool retrieves the gen_pool for a given device node and property name, where the property must contain a phandle pointing to a platform device node. The corresponding platform device is then fed into dev_get_gen_pool and the resulting gen_pool is returned. Signed-off-by: Philipp Zabel Acked-by: Grant Likely --- include/linux/genalloc.h | 15 + lib/genalloc.c | 81 ++ 2 files changed, 96 insertions(+) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index dd7c569..383e8f4 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -105,4 +105,19 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data); +extern struct gen_pool *devm_gen_pool_create(struct device *dev, + int min_alloc_order, int nid); +extern struct gen_pool *dev_get_gen_pool(struct device *dev); + +struct device_node; +#ifdef CONFIG_OF +extern struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index); +#else +inline struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + return NULL; +} +#endif #endif /* __GENALLOC_H__ */ diff --git a/lib/genalloc.c b/lib/genalloc.c index 5492043..b35cfa9 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) { @@ -480,3 +482,82 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, return start_bit; } EXPORT_SYMBOL(gen_pool_best_fit); + +static void devm_gen_pool_release(struct device *dev, void *res) +{ + gen_pool_destroy(*(struct gen_pool **)res); +} + +/** + * devm_gen_pool_create - managed gen_pool_create + * @dev: device that provides the gen_pool + * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents + * @nid: node id of the node the pool structure should be allocated on, or -1 + * + * Create a new special memory pool that can be used to manage special purpose + * memory not managed by the regular kmalloc/kfree interface. The pool will be + * automatically destroyed by the device management code. + */ +struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, + int nid) +{ + struct gen_pool **ptr, *pool; + + ptr = devres_alloc(devm_gen_pool_release, sizeof(*ptr), GFP_KERNEL); + + pool = gen_pool_create(min_alloc_order, nid); + if (pool) { + *ptr = pool; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return pool; +} + +/** + * dev_get_gen_pool - Obtain the gen_pool (if any) for a device + * @dev: device to retrieve the gen_pool from + * @name: Optional name for the gen_pool, usually NULL + * + * Returns the gen_pool for the device if one is present, or NULL. + */ +struct gen_pool *dev_get_gen_pool(struct device *dev) +{ + struct gen_pool **p = devres_find(dev, devm_gen_pool_release, NULL, + NULL); + + if (!p) + return NULL; + return *p; +} +EXPORT_SYMBOL_GPL(dev_get_gen_pool); + +#ifdef CONFIG_OF +/** + * of_get_named_gen_pool - find a pool by phandle property + * @np: device node + * @propname: property name containing phandle(s) + * @index: index into the phandle array + * + * Returns the pool that contains the chunk starting at the physical + * address of the device tree node pointed at by the phandle property, + * or NULL if not found. + */ +struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + struct platform_device *pdev; + struct device_node *np_pool; + + np_pool = of_parse_phandle(np, propname, index); + if (!np_pool) + return NULL; + pdev = of_find_device_by_node(np_pool); + if (!pdev) + return NULL; + return dev_get_gen_pool(&pdev->dev); +} +EXPORT_SYMBOL_GPL(of_get_named_gen_pool); +#endif /* CONFIG_OF */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Pleas
[PATCH v9 RESEND 3/4] media: coda: use genalloc API
This patch depends on "genalloc: add devres support, allow to find a managed pool by device", which provides the of_get_named_gen_pool and dev_get_gen_pool functions. Signed-off-by: Philipp Zabel Acked-By: Javier Martin Acked-by: Grant Likely --- Documentation/devicetree/bindings/media/coda.txt | 30 +++ drivers/media/platform/Kconfig |1 - drivers/media/platform/coda.c| 45 +++--- include/linux/platform_data/coda.h | 18 + 4 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/coda.txt create mode 100644 include/linux/platform_data/coda.h diff --git a/Documentation/devicetree/bindings/media/coda.txt b/Documentation/devicetree/bindings/media/coda.txt new file mode 100644 index 000..2865d04 --- /dev/null +++ b/Documentation/devicetree/bindings/media/coda.txt @@ -0,0 +1,30 @@ +Chips&Media Coda multi-standard codec IP + + +Coda codec IPs are present in i.MX SoCs in various versions, +called VPU (Video Processing Unit). + +Required properties: +- compatible : should be "fsl,-src" for i.MX SoCs: + (a) "fsl,imx27-vpu" for CodaDx6 present in i.MX27 + (b) "fsl,imx53-vpu" for CODA7541 present in i.MX53 + (c) "fsl,imx6q-vpu" for CODA960 present in i.MX6q +- reg: should be register base and length as documented in the + SoC reference manual +- interrupts : Should contain the VPU interrupt. For CODA960, + a second interrupt is needed for the MJPEG unit. +- clocks : Should contain the ahb and per clocks, in the order + determined by the clock-names property. +- clock-names : Should be "ahb", "per" +- iram : phandle pointing to the SRAM device node + +Example: + +vpu: vpu@63ff4000 { + compatible = "fsl,imx53-vpu"; + reg = <0x63ff4000 0x1000>; + interrupts = <9>; + clocks = <&clks 63>, <&clks 63>; + clock-names = "ahb", "per"; + iram = <&ocram>; +}; diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 05d7b63..bbf83c1 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -145,7 +145,6 @@ config VIDEO_CODA depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV - select IRAM_ALLOC if SOC_IMX53 ---help--- Coda is a range of video codec IPs that supports H.264, MPEG-4, and other video formats. diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 20827ba..b931c2a 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -43,6 +44,7 @@ #define CODA7_WORK_BUF_SIZE(512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024) #define CODA_PARA_BUF_SIZE (10 * 1024) #define CODA_ISRAM_SIZE(2048 * 2) +#define CODADX6_IRAM_SIZE 0xb000 #define CODA7_IRAM_SIZE0x14000 /* 81920 bytes */ #define CODA_MAX_FRAMEBUFFERS 2 @@ -128,7 +130,10 @@ struct coda_dev { struct coda_aux_buf codebuf; struct coda_aux_buf workbuf; + struct gen_pool *iram_pool; + long unsigned int iram_vaddr; long unsigned int iram_paddr; + unsigned long iram_size; spinlock_t irqlock; struct mutexdev_mutex; @@ -1926,6 +1931,9 @@ static int coda_probe(struct platform_device *pdev) const struct of_device_id *of_id = of_match_device(of_match_ptr(coda_dt_ids), &pdev->dev); const struct platform_device_id *pdev_id; + struct coda_platform_data *pdata = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; + struct gen_pool *pool; struct coda_dev *dev; struct resource *res; int ret, irq; @@ -1988,6 +1996,16 @@ static int coda_probe(struct platform_device *pdev) return -ENOENT; } + /* Get IRAM pool from device tree or platform data */ + pool = of_get_named_gen_pool(np, "iram", 0); + if (!pool && pdata) + pool = dev_get_gen_pool(pdata->iram_dev); + if (!pool) { + dev_err(&pdev->dev, "iram pool not available\n"); + return -ENOMEM; + } + dev->iram_pool = pool; + ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) return ret; @@ -2022,18 +2040,17 @@ static int coda_probe(struct platform_device *pdev)
[PATCH v9 RESEND 2/4] misc: Generic on-chip SRAM allocation driver
This driver requests and remaps a memory region as configured in the device tree. It serves memory from this region via the genalloc API. It optionally enables the SRAM clock. Other drivers can retrieve the genalloc pool from a phandle pointing to this drivers' device node in the device tree. The allocation granularity is hard-coded to 32 bytes for now, to make the SRAM driver useful for the 6502 remoteproc driver. There is overhead for bigger SRAMs, where only a much coarser allocation granularity is needed: At 32 bytes minimum allocation size, a 256 KiB SRAM needs a 1 KiB bitmap to track allocations. Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo Acked-by: Grant Likely --- Changes since v8: - Changed device tree compatible string to "mmio-sram" --- Documentation/devicetree/bindings/misc/sram.txt | 16 +++ drivers/misc/Kconfig|9 ++ drivers/misc/Makefile |1 + drivers/misc/sram.c | 121 +++ 4 files changed, 147 insertions(+) create mode 100644 Documentation/devicetree/bindings/misc/sram.txt create mode 100644 drivers/misc/sram.c diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt new file mode 100644 index 000..4d0a00e --- /dev/null +++ b/Documentation/devicetree/bindings/misc/sram.txt @@ -0,0 +1,16 @@ +Generic on-chip SRAM + +Simple IO memory regions to be managed by the genalloc API. + +Required properties: + +- compatible : mmio-sram + +- reg : SRAM iomem address range + +Example: + +sram: sram@5c00 { + compatible = "mmio-sram"; + reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ +}; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index e83fdfe..4878507 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -510,6 +510,15 @@ config LATTICE_ECP3_CONFIG If unsure, say N. +config SRAM + bool "Generic on-chip SRAM driver" + depends on HAS_IOMEM + select GENERIC_ALLOCATOR + help + This driver allows to declare a memory region to be managed + by the genalloc API. It is supposed to be used for small + on-chip SRAM areas found on many SoCs. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 35a1463..08e2007 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -52,3 +52,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/ obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o +obj-$(CONFIG_SRAM) += sram.o diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c new file mode 100644 index 000..7858c62 --- /dev/null +++ b/drivers/misc/sram.c @@ -0,0 +1,121 @@ +/* + * Generic on-chip SRAM allocation driver + * + * Copyright (C) 2012 Philipp Zabel, Pengutronix + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SRAM_GRANULARITY 32 + +struct sram_dev { + struct gen_pool *pool; + struct clk *clk; +}; + +static int sram_probe(struct platform_device *pdev) +{ + void __iomem *virt_base; + struct sram_dev *sram; + struct resource *res; + unsigned long size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + size = resource_size(res); + + virt_base = devm_request_and_ioremap(&pdev->dev, res); + if (!virt_base) + return -EADDRNOTAVAIL; + + sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL); + if (!sram) + return -ENOMEM; + + sram->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(sram->clk)) + sram->clk = NULL; + else + clk_prepare_enable(sram->clk); + + sram->pool = devm_gen_pool_create(&pdev->dev, ilog2(SRAM_GRANULA
[PATCH v8 0/4] Add generic driver for on-chip SRAM
These patches add support to configure on-chip SRAM via device-tree node or platform data and to obtain the resulting genalloc pool from the struct device pointer or a phandle pointing at the device tree node. This allows drivers to allocate SRAM with the genalloc API without hard-coding the genalloc pool pointer. I changed the implementation in genalloc.c since v7. To avoid the global pool list, a devres managed version of gen_pool_create is added, and gen_pool_find_by_phys of the previous versions is replaced by dev_get_gen_pool, that retrieves a gen_pool created with devm_gen_pool_create from the corresponding device pointer. of_get_named_gen_pool is called unchanged. The on-chip SRAM on i.MX53 and i.MX6q can be registered via device tree and changed to use the simple generic SRAM driver: ocram: ocram@0090 { compatible = "fsl,imx-ocram", "sram"; reg = <0x0090 0x3f000>; }; A driver that needs to allocate SRAM buffers, like the video processing unit on i.MX53, can retrieve the genalloc pool from a phandle in the device tree using of_get_named_gen_pool(node, "iram", 0) from patch 1: vpu@63ff4000 { /* ... */ iram = <&ocram>; }; Changes since v7: - Removed the global pool list in genalloc. Instead, added a devres managed version of gen_pool_create, replacing gen_pool_find_by_phys with dev_get_gen_pool (and made of_get_named_gen_pool use that) - In the coda driver, switched to dev_get_gen_pool and added a platform_data struct to pass the SRAM device pointer (instead of using a second IO memory resource). Added device tree binding documentation. regards Philipp --- Documentation/devicetree/bindings/media/coda.txt | 30 ++ Documentation/devicetree/bindings/misc/sram.txt | 17 +++ arch/arm/boot/dts/imx53.dtsi |5 + arch/arm/boot/dts/imx6q.dtsi |6 ++ drivers/media/platform/Kconfig |1 - drivers/media/platform/coda.c| 45 +--- drivers/misc/Kconfig |9 ++ drivers/misc/Makefile|1 + drivers/misc/sram.c | 121 ++ include/linux/genalloc.h | 15 +++ include/linux/platform_data/coda.h | 18 lib/genalloc.c | 81 +++ 12 files changed, 334 insertions(+), 15 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v8 4/4] ARM: dts: add sram for imx53 and imx6q
Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo --- arch/arm/boot/dts/imx53.dtsi |5 + arch/arm/boot/dts/imx6q.dtsi |6 ++ 2 files changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index edc3f1e..8faca1a 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -664,5 +664,10 @@ status = "disabled"; }; }; + + ocram: ocram@f800 { + compatible = "fsl,imx-ocram", "sram"; + reg = <0xf800 0x2>; + }; }; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index d6265ca..740e714 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -124,6 +124,12 @@ status = "disabled"; }; + ocram: ocram@0090 { + compatible = "fsl,imx-ocram", "sram"; + reg = <0x0090 0x3f000>; + clocks = <&clks 142>; + }; + timer@00a00600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x00a00600 0x20>; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v8 1/4] genalloc: add devres support, allow to find a managed pool by device
This patch adds three exported functions to lib/genalloc.c: devm_gen_pool_create, dev_get_gen_pool, and of_get_named_gen_pool. devm_gen_pool_create is a managed version of gen_pool_create that keeps track of the pool via devres and allows the management code to automatically destroy it after device removal. dev_get_gen_pool retrieves the gen_pool for a given device, if it was created with devm_gen_pool_create, using devres_find. of_get_named_gen_pool retrieves the gen_pool for a given device node and property name, where the property must contain a phandle pointing to a platform device node. The corresponding platform device is then fed into dev_get_gen_pool and the resulting gen_pool is returned. Signed-off-by: Philipp Zabel --- Changes since v7: - Removed the global pool list. Instead, added a devres managed version of gen_pool_create, replacing gen_pool_find_by_phys with dev_get_gen_pool --- include/linux/genalloc.h | 15 + lib/genalloc.c | 81 ++ 2 files changed, 96 insertions(+) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index dd7c569..383e8f4 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -105,4 +105,19 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data); +extern struct gen_pool *devm_gen_pool_create(struct device *dev, + int min_alloc_order, int nid); +extern struct gen_pool *dev_get_gen_pool(struct device *dev); + +struct device_node; +#ifdef CONFIG_OF +extern struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index); +#else +inline struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + return NULL; +} +#endif #endif /* __GENALLOC_H__ */ diff --git a/lib/genalloc.c b/lib/genalloc.c index 5492043..b35cfa9 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) { @@ -480,3 +482,82 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, return start_bit; } EXPORT_SYMBOL(gen_pool_best_fit); + +static void devm_gen_pool_release(struct device *dev, void *res) +{ + gen_pool_destroy(*(struct gen_pool **)res); +} + +/** + * devm_gen_pool_create - managed gen_pool_create + * @dev: device that provides the gen_pool + * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents + * @nid: node id of the node the pool structure should be allocated on, or -1 + * + * Create a new special memory pool that can be used to manage special purpose + * memory not managed by the regular kmalloc/kfree interface. The pool will be + * automatically destroyed by the device management code. + */ +struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, + int nid) +{ + struct gen_pool **ptr, *pool; + + ptr = devres_alloc(devm_gen_pool_release, sizeof(*ptr), GFP_KERNEL); + + pool = gen_pool_create(min_alloc_order, nid); + if (pool) { + *ptr = pool; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return pool; +} + +/** + * dev_get_gen_pool - Obtain the gen_pool (if any) for a device + * @dev: device to retrieve the gen_pool from + * @name: Optional name for the gen_pool, usually NULL + * + * Returns the gen_pool for the device if one is present, or NULL. + */ +struct gen_pool *dev_get_gen_pool(struct device *dev) +{ + struct gen_pool **p = devres_find(dev, devm_gen_pool_release, NULL, + NULL); + + if (!p) + return NULL; + return *p; +} +EXPORT_SYMBOL_GPL(dev_get_gen_pool); + +#ifdef CONFIG_OF +/** + * of_get_named_gen_pool - find a pool by phandle property + * @np: device node + * @propname: property name containing phandle(s) + * @index: index into the phandle array + * + * Returns the pool that contains the chunk starting at the physical + * address of the device tree node pointed at by the phandle property, + * or NULL if not found. + */ +struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + struct platform_device *pdev; + struct device_node *np_pool; + + np_pool = of_parse_phandle(np, propname, index); + if (!np_pool) + return NULL; + pdev = of_find_device_by_node(np_pool); + if (!pdev) + return NULL; + return dev_get_gen_pool(&pdev->dev); +} +EXPORT_SYMBOL_GPL(of_get_named_gen_pool); +#endif /* CONFIG_OF */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe
[PATCH v8 2/4] misc: Generic on-chip SRAM allocation driver
This driver requests and remaps a memory region as configured in the device tree. It serves memory from this region via the genalloc API. It optionally enables the SRAM clock. Other drivers can retrieve the genalloc pool from a phandle pointing to this drivers' device node in the device tree. The allocation granularity is hard-coded to 32 bytes for now, to make the SRAM driver useful for the 6502 remoteproc driver. There is overhead for bigger SRAMs, where only a much coarser allocation granularity is needed: At 32 bytes minimum allocation size, a 256 KiB SRAM needs a 1 KiB bitmap to track allocations. Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo --- Changes since v7: - Removed obsolete __devinit/__devexit/__devexit_p --- Documentation/devicetree/bindings/misc/sram.txt | 17 drivers/misc/Kconfig|9 ++ drivers/misc/Makefile |1 + drivers/misc/sram.c | 121 +++ 4 files changed, 148 insertions(+) create mode 100644 Documentation/devicetree/bindings/misc/sram.txt create mode 100644 drivers/misc/sram.c diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt new file mode 100644 index 000..b64136c --- /dev/null +++ b/Documentation/devicetree/bindings/misc/sram.txt @@ -0,0 +1,17 @@ +Generic on-chip SRAM + +Simple IO memory regions to be managed by the genalloc API. + +Required properties: + +- compatible : sram + +- reg : SRAM iomem address range + +Example: + +sram: sram@5c00 { + compatible = "sram"; + reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ +}; + diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index e83fdfe..4878507 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -510,6 +510,15 @@ config LATTICE_ECP3_CONFIG If unsure, say N. +config SRAM + bool "Generic on-chip SRAM driver" + depends on HAS_IOMEM + select GENERIC_ALLOCATOR + help + This driver allows to declare a memory region to be managed + by the genalloc API. It is supposed to be used for small + on-chip SRAM areas found on many SoCs. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 35a1463..08e2007 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -52,3 +52,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/ obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o +obj-$(CONFIG_SRAM) += sram.o diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c new file mode 100644 index 000..94d12ea --- /dev/null +++ b/drivers/misc/sram.c @@ -0,0 +1,121 @@ +/* + * Generic on-chip SRAM allocation driver + * + * Copyright (C) 2012 Philipp Zabel, Pengutronix + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SRAM_GRANULARITY 32 + +struct sram_dev { + struct gen_pool *pool; + struct clk *clk; +}; + +static int sram_probe(struct platform_device *pdev) +{ + void __iomem *virt_base; + struct sram_dev *sram; + struct resource *res; + unsigned long size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + size = resource_size(res); + + virt_base = devm_request_and_ioremap(&pdev->dev, res); + if (!virt_base) + return -EADDRNOTAVAIL; + + sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL); + if (!sram) + return -ENOMEM; + + sram->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(sram->clk)) + sram->clk = NULL; + else + clk_prepare_enable(sram->clk); + + sram->pool = devm_gen_pool_create(&pdev->dev, ilog2(SRAM_GRANULARITY), -1); + if (!sram->p
[PATCH v8 3/4] media: coda: use genalloc API
This patch depends on "genalloc: add devres support, allow to find a managed pool by device", which provides the of_get_named_gen_pool and dev_get_gen_pool functions. Signed-off-by: Philipp Zabel --- Changes since v7: - In the platform data case, retrieve gen_pool by device instead of by physical address. The information about the SRAM pool can't be provided via memory resource, so add a platform data struct that contains a pointer to the SRAM device. - Add device tree binding documentation. --- Documentation/devicetree/bindings/media/coda.txt | 30 +++ drivers/media/platform/Kconfig |1 - drivers/media/platform/coda.c| 45 +++--- include/linux/platform_data/coda.h | 18 + 4 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/coda.txt create mode 100644 include/linux/platform_data/coda.h diff --git a/Documentation/devicetree/bindings/media/coda.txt b/Documentation/devicetree/bindings/media/coda.txt new file mode 100644 index 000..2865d04 --- /dev/null +++ b/Documentation/devicetree/bindings/media/coda.txt @@ -0,0 +1,30 @@ +Chips&Media Coda multi-standard codec IP + + +Coda codec IPs are present in i.MX SoCs in various versions, +called VPU (Video Processing Unit). + +Required properties: +- compatible : should be "fsl,-src" for i.MX SoCs: + (a) "fsl,imx27-vpu" for CodaDx6 present in i.MX27 + (b) "fsl,imx53-vpu" for CODA7541 present in i.MX53 + (c) "fsl,imx6q-vpu" for CODA960 present in i.MX6q +- reg: should be register base and length as documented in the + SoC reference manual +- interrupts : Should contain the VPU interrupt. For CODA960, + a second interrupt is needed for the MJPEG unit. +- clocks : Should contain the ahb and per clocks, in the order + determined by the clock-names property. +- clock-names : Should be "ahb", "per" +- iram : phandle pointing to the SRAM device node + +Example: + +vpu: vpu@63ff4000 { + compatible = "fsl,imx53-vpu"; + reg = <0x63ff4000 0x1000>; + interrupts = <9>; + clocks = <&clks 63>, <&clks 63>; + clock-names = "ahb", "per"; + iram = <&ocram>; +}; diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 05d7b63..bbf83c1 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -145,7 +145,6 @@ config VIDEO_CODA depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV - select IRAM_ALLOC if SOC_IMX53 ---help--- Coda is a range of video codec IPs that supports H.264, MPEG-4, and other video formats. diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 20827ba..b931c2a 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -43,6 +44,7 @@ #define CODA7_WORK_BUF_SIZE(512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024) #define CODA_PARA_BUF_SIZE (10 * 1024) #define CODA_ISRAM_SIZE(2048 * 2) +#define CODADX6_IRAM_SIZE 0xb000 #define CODA7_IRAM_SIZE0x14000 /* 81920 bytes */ #define CODA_MAX_FRAMEBUFFERS 2 @@ -128,7 +130,10 @@ struct coda_dev { struct coda_aux_buf codebuf; struct coda_aux_buf workbuf; + struct gen_pool *iram_pool; + long unsigned int iram_vaddr; long unsigned int iram_paddr; + unsigned long iram_size; spinlock_t irqlock; struct mutexdev_mutex; @@ -1926,6 +1931,9 @@ static int coda_probe(struct platform_device *pdev) const struct of_device_id *of_id = of_match_device(of_match_ptr(coda_dt_ids), &pdev->dev); const struct platform_device_id *pdev_id; + struct coda_platform_data *pdata = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; + struct gen_pool *pool; struct coda_dev *dev; struct resource *res; int ret, irq; @@ -1988,6 +1996,16 @@ static int coda_probe(struct platform_device *pdev) return -ENOENT; } + /* Get IRAM pool from device tree or platform data */ + pool = of_get_named_gen_pool(np, "iram", 0); + if (!pool && pdata) + pool = dev_get_gen_pool(pdata->iram_dev); + if (!pool) { + dev_err(&pdev->dev, "iram pool not available\n"); + re
[GIT PULL] drbd build fix in case CONFIG_CRYPTO_HMAC is not set
The following changes since commit d88c3ab963d4cce09b25ef661b871bd7af6dad0d: drbd: only fail empty flushes if no good data is reachable (2013-01-30 10:40:33 +0100) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens-3.8-fix for you to fetch changes up to 78aa7987a223e8542f2735dace439690c6171ac5: drbd: Fix build error when CONFIG_CRYPTO_HMAC is not set (2013-02-04 18:14:03 +0100) Philipp Reisner (1): drbd: Fix build error when CONFIG_CRYPTO_HMAC is not set drivers/block/drbd/drbd_receiver.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index a9eccfc..6e27dde 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -4659,8 +4659,8 @@ static int drbd_do_features(struct drbd_tconn *tconn) #if !defined(CONFIG_CRYPTO_HMAC) && !defined(CONFIG_CRYPTO_HMAC_MODULE) static int drbd_do_auth(struct drbd_tconn *tconn) { - dev_err(DEV, "This kernel was build without CONFIG_CRYPTO_HMAC.\n"); - dev_err(DEV, "You need to disable 'cram-hmac-alg' in drbd.conf.\n"); + conn_err(tconn, "This kernel was build without CONFIG_CRYPTO_HMAC.\n"); + conn_err(tconn, "You need to disable 'cram-hmac-alg' in drbd.conf.\n"); return -1; } #else -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v8 2/4] misc: Generic on-chip SRAM allocation driver
Am Dienstag, den 05.02.2013, 00:53 +0900 schrieb Paul Mundt: > On Mon, Feb 04, 2013 at 12:32:16PM +0100, Philipp Zabel wrote: > > This driver requests and remaps a memory region as configured in the > > device tree. It serves memory from this region via the genalloc API. > > It optionally enables the SRAM clock. > > > > Other drivers can retrieve the genalloc pool from a phandle pointing > > to this drivers' device node in the device tree. > > > > The allocation granularity is hard-coded to 32 bytes for now, > > to make the SRAM driver useful for the 6502 remoteproc driver. > > There is overhead for bigger SRAMs, where only a much coarser > > allocation granularity is needed: At 32 bytes minimum allocation > > size, a 256 KiB SRAM needs a 1 KiB bitmap to track allocations. > > > > Signed-off-by: Philipp Zabel > > Reviewed-by: Shawn Guo > > How exactly is this "generic" if you have randomly hard-coded an > allocation granularity that is larger than half of the in-tree SRAM pool > users today can even support? Did you even bother to look at in-tree SRAM > pool users other than the one you are working on? I agree it should be configurable. As stated in the thread pointed out by Matt, I'd just like to separate the discussion about the device tree bindings for the allocation granularity from this patchset. About the "generic" labeling, I had a look around for users of gen_pool_create() - I admit to overlooking arch/sh/mm/sram.c, and most of the others (except arch/arm/kernel/tcm.c drivers/acpi/apei/ghes.c, both of which I didn't consider potential users of the sram driver) seem to use a granularity significantly larger than 32 bytes. > There also doesn't seem to be any real reason for the hard-coding either, > this information could easily be fetched via platform data or the device > tree, True. Although the device tree is supposed to describe the hardware. The allocation granularity is an implementation detail of the gen_pool allocator (or possibly kind of a hardware detail of the gen_pool user, if there are alignment requirements). That is why I didn't want to press on with the device tree granularity configuration part yet. > and the driver in question would simply need to be able to > determine whether the size is suitable for it or not. Sounds sensible to me. I'd like to follow up with Matt's patch and something like this in a second step. regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] drbd build fix in case CONFIG_CRYPTO_HMAC is not set
> NOT pulled. Base the branch off my for-linus. When I pull the below into > that, I don't get a small patch, I get all changes from 3.7 to 3.8-rc5. Ok, now based on your for-linus. The following changes since commit 1383923d1985cef2bceb8128094fbe5e05de7435: Merge branch 'for-jens' of git://git.drbd.org/linux-drbd into for-linus (2013-01-22 08:22:11 -0700) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens-3.8-fix for you to fetch changes up to 23c275cba16615ac8cd3815cb1a86fd64cf12aa6: drbd: Fix build error when CONFIG_CRYPTO_HMAC is not set (2013-02-05 15:58:34 +0100) ---- Philipp Reisner (1): drbd: Fix build error when CONFIG_CRYPTO_HMAC is not set drivers/block/drbd/drbd_receiver.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index a9eccfc..6e27dde 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -4659,8 +4659,8 @@ static int drbd_do_features(struct drbd_tconn *tconn) #if !defined(CONFIG_CRYPTO_HMAC) && !defined(CONFIG_CRYPTO_HMAC_MODULE) static int drbd_do_auth(struct drbd_tconn *tconn) { - dev_err(DEV, "This kernel was build without CONFIG_CRYPTO_HMAC.\n"); - dev_err(DEV, "You need to disable 'cram-hmac-alg' in drbd.conf.\n"); + conn_err(tconn, "This kernel was build without CONFIG_CRYPTO_HMAC.\n"); + conn_err(tconn, "You need to disable 'cram-hmac-alg' in drbd.conf.\n"); return -1; } #else -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v8 2/4] misc: Generic on-chip SRAM allocation driver
Hi Grant, Am Freitag, den 08.02.2013, 20:16 + schrieb Grant Likely: > On Mon, 4 Feb 2013 12:32:16 +0100, Philipp Zabel > wrote: > > This driver requests and remaps a memory region as configured in the > > device tree. It serves memory from this region via the genalloc API. > > It optionally enables the SRAM clock. > > > > Other drivers can retrieve the genalloc pool from a phandle pointing > > to this drivers' device node in the device tree. > > > > The allocation granularity is hard-coded to 32 bytes for now, > > to make the SRAM driver useful for the 6502 remoteproc driver. > > There is overhead for bigger SRAMs, where only a much coarser > > allocation granularity is needed: At 32 bytes minimum allocation > > size, a 256 KiB SRAM needs a 1 KiB bitmap to track allocations. > > > > Signed-off-by: Philipp Zabel > > Reviewed-by: Shawn Guo > > --- > > Changes since v7: > > - Removed obsolete __devinit/__devexit/__devexit_p > > --- > > Documentation/devicetree/bindings/misc/sram.txt | 17 > > drivers/misc/Kconfig|9 ++ > > drivers/misc/Makefile |1 + > > drivers/misc/sram.c | 121 > > +++ > > 4 files changed, 148 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/misc/sram.txt > > create mode 100644 drivers/misc/sram.c > > > > diff --git a/Documentation/devicetree/bindings/misc/sram.txt > > b/Documentation/devicetree/bindings/misc/sram.txt > > new file mode 100644 > > index 000..b64136c > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/misc/sram.txt > > @@ -0,0 +1,17 @@ > > +Generic on-chip SRAM > > + > > +Simple IO memory regions to be managed by the genalloc API. > > + > > +Required properties: > > + > > +- compatible : sram > > I'm a little concerned that 'sram' is just too generic for a compatible > value and we may end up needing a blacklist of systems where the sram > device should not be driven with this driver. If you can think of > a more descriptive name here then I would use it. various SoC vendors call this (variations of) "on-chip" or "internal" SRAM/memory. "on-chip-sram" or "internal-sram" are still plenty generic, though. How about "mmio-sram", as opposed to an SRAM that needs more than the simple mmio region handled by this driver? An alternative would be to use the vendor specific names and grow a compatible list in the driver ("fsl,ocram", "ti,ocm", ...). > However, I'm not worried about it enough to nak it and the rest of the > series looks fine. > > Acked-by: Grant Likely Thank you. regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] drbd activity log improvements for the 3.9 merge window
Hi Jens, this is our contribution to the next merge-window: With this release we have three important improvements to the activity log: 1 Starting with 8.4.3 the activity log has a variable size on disk (before it was fixed 32KiByte). -> The limitation of 6433 on the al-extents option is no longer. 2 The activity log can be organised as a stripe set in the meta-data. 3 Never block a caller submitting a BIO, but hand off the writing of AL-updates to a dedicated worker thread. (In the past DRBD blocked the caller when a submitted BIO is not covered by the current active set, until the transaction was written into the AL.) With these changed we see substantial improvement in overall IOPs, on workloads that are bigger than the active set (al-extents * 4MiB) The following changes since commit 478c030eecbec927d62561c5f48a4515ea0fa21a: drivers/block/mtip32xx/mtip32xx.c:1726:5: sparse: symbol 'mtip_send_trim' was not declared. Should it be static? (2013-01-12 09:15:19 +0100) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens-3.9-drivers for you to fetch changes up to 99cb6a9f0230ed31b712c48983a2ce9ca20a30e1: drbd: adjust upper limit for activity log extents (2013-01-30 10:19:58 +0100) Lars Ellenberg (18): drbd: cleanup bogus assert message drbd: cleanup ondisk meta data layout calculations and defines drbd: prepare for new striped layout of activity log drbd: use the cached meta_dev_idx drbd: mechanically rename la_size to la_size_sect drbd: read meta data early, base on-disk offsets on super block drbd: Clarify when activity log I/O is delegated to the worker thread drbd: drbd_al_being_io: short circuit to reduce latency drbd: split __drbd_make_request in before and after drbd_al_begin_io drbd: prepare to queue write requests on a submit worker drbd: split drbd_al_begin_io into fastpath, prepare, and commit drbd: split out some helper functions to drbd_al_begin_io drbd: queue writes on submitter thread, unless they pass the activity log fastpath lru_cache: introduce lc_get_cumulative() drbd: consolidate as many updates as possible into one AL transaction drbd: move start io accounting before activity log transaction drbd: try hard to max out the updates per AL transaction drbd: adjust upper limit for activity log extents Philipp Reisner (7): drbd: reset ap_in_flight counter for new connections drbd: abort start of resync early, if it raced with connection breakage drbd: move invalidating the whole bitmap out of after_state ch() drbd: fix effective error returned when refusing an invalidate drbd: drop now useless duplicate state request from invalidate drbd: fix spurious warning about bitmap being locked from detach drbd: Fix disconnect to keep the peer disk state if connection breaks during operation drivers/block/drbd/drbd_actlog.c | 246 ++- drivers/block/drbd/drbd_bitmap.c | 13 +- drivers/block/drbd/drbd_int.h | 179 +- drivers/block/drbd/drbd_main.c | 249 ++-- drivers/block/drbd/drbd_nl.c | 194 +--- drivers/block/drbd/drbd_receiver.c |5 +- drivers/block/drbd/drbd_req.c | 166 +--- drivers/block/drbd/drbd_state.c| 28 ++-- drivers/block/drbd/drbd_strings.c |1 + drivers/block/drbd/drbd_worker.c |9 +- include/linux/drbd.h |5 +- include/linux/drbd_limits.h| 11 +- include/linux/lru_cache.h |1 + lib/lru_cache.c| 55 ++-- 14 files changed, 842 insertions(+), 320 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] drbd: Fix flushes without data on a diskless primary node
Hi Jens, Please consider to forward this fix for 3.8 to Linus. The following changes since commit 949db153b6466c6f7cad5a427ecea94985927311: Linux 3.8-rc5 (2013-01-25 11:57:28 -0800) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens-3.8-fix for you to fetch changes up to d88c3ab963d4cce09b25ef661b871bd7af6dad0d: drbd: only fail empty flushes if no good data is reachable (2013-01-30 10:40:33 +0100) Lars Ellenberg (1): drbd: only fail empty flushes if no good data is reachable drivers/block/drbd/drbd_req.c | 12 drivers/block/drbd/drbd_req.h |8 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index f58a4a4..41bb058 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -263,8 +263,7 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m) else root = &mdev->read_requests; drbd_remove_request_interval(root, req); - } else if (!(s & RQ_POSTPONED)) - D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); + } /* Before we can signal completion to the upper layers, * we may need to close the current transfer log epoch. @@ -755,6 +754,11 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, D_ASSERT(req->rq_state & RQ_NET_PENDING); mod_rq_state(req, m, RQ_NET_PENDING, RQ_NET_OK|RQ_NET_DONE); break; + + case QUEUE_AS_DRBD_BARRIER: + start_new_tl_epoch(mdev->tconn); + mod_rq_state(req, m, 0, RQ_NET_OK|RQ_NET_DONE); + break; }; return rv; @@ -975,8 +979,8 @@ static int drbd_process_write_request(struct drbd_request *req) /* The only size==0 bios we expect are empty flushes. */ D_ASSERT(req->master_bio->bi_rw & REQ_FLUSH); if (remote) - start_new_tl_epoch(mdev->tconn); - return 0; + _req_mod(req, QUEUE_AS_DRBD_BARRIER); + return remote; } if (!remote && !send_oos) diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index 016de6b..c407f4a 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h @@ -88,6 +88,14 @@ enum drbd_req_event { QUEUE_FOR_NET_READ, QUEUE_FOR_SEND_OOS, + /* An empty flush is queued as P_BARRIER, +* which will cause it to complete "successfully", +* even if the local disk flush failed. +* +* Just like "real" requests, empty flushes (blkdev_issue_flush()) will +* only see an error if neither local nor remote data is reachable. */ + QUEUE_AS_DRBD_BARRIER, + SEND_CANCELED, SEND_FAILED, HANDED_OVER_TO_NETWORK, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 8/9] ARM: i.MX6: use generic on-chip SRAM allocator driver for OCRAM
Signed-off-by: Philipp Zabel --- arch/arm/boot/dts/imx6q.dtsi |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 9cb0b50..1e463c4 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -111,8 +111,8 @@ status = "disabled"; }; - ocram@0090 { - compatible = "fsl,imx-ocram"; + ocram: ocram@0090 { + compatible = "fsl,imx-ocram", "sram"; reg = <0x0090 0x3f000>; }; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 7/9] ARM: i.MX53: use generic on-chip SRAM allocator driver for OCRAM
Signed-off-by: Philipp Zabel --- arch/arm/boot/dts/imx53.dtsi |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 5da342a..2767a92 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -338,8 +338,8 @@ }; }; - ocram@f800 { - compatible = "fsl,imx-ocram"; + ocram: ocram@f800 { + compatible = "fsl,imx-ocram", "sram"; reg = <0xf800 0x2>; }; }; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 6/9] misc: Generic on-chip SRAM allocation driver
This driver requests and remaps a memory region as configured in the device tree. It serves memory from this region via the genalloc API. Other drivers can retrieve the genalloc pool from a phandle pointing to this drivers' device node in the device tree. Signed-off-by: Philipp Zabel --- drivers/misc/Kconfig |8 drivers/misc/Makefile |1 + drivers/misc/sram.c | 105 + 3 files changed, 114 insertions(+) create mode 100644 drivers/misc/sram.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 98a442d..8a55284 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -509,6 +509,14 @@ config USB_SWITCH_FSA9480 stereo and mono audio, video, microphone and UART data to use a common connector port. +config SRAM + bool "Generic on-chip SRAM driver\n" + select GENERIC_ALLOCATOR + help + This driver allows to declare a memory region to be managed + by the genalloc API. It is supposed to be used for small + on-chip SRAM areas found on many ARM SoCs. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b88df7a..ccc759a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -50,3 +50,4 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_INTEL_MEI)+= mei/ +obj-$(CONFIG_SRAM) += sram.o diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c new file mode 100644 index 000..c5cf67e --- /dev/null +++ b/drivers/misc/sram.c @@ -0,0 +1,105 @@ +/* + * Generic on-chip SRAM allocation driver + * + * Copyright (C) 2012 Philipp Zabel, Pengutronix + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct sram_dev { + struct gen_pool *pool; +}; + +static int __devinit sram_probe(struct platform_device *pdev) +{ + void __iomem *virt_base; + struct sram_dev *sram; + struct resource *res; + unsigned long size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + size = resource_size(res); + + virt_base = devm_request_and_ioremap(&pdev->dev, res); + if (!virt_base) + return -ENOMEM; + + sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL); + if (!sram) + return -ENOMEM; + + sram->pool = gen_pool_create(PAGE_SHIFT, -1); + if (!sram->pool) + return -ENOMEM; + + ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base, + res->start, size, -1); + if (ret < 0) { + gen_pool_destroy(sram->pool); + return ret; + } + + platform_set_drvdata(pdev, sram); + + dev_dbg(&pdev->dev, "SRAM pool: %ld KiB @ 0x%p\n", size / 1024, virt_base); + + return 0; +} + +static int __devexit sram_remove(struct platform_device *pdev) +{ + struct sram_dev *sram = platform_get_drvdata(pdev); + + if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool)) + dev_dbg(&pdev->dev, "removed while SRAM allocated\n"); + + gen_pool_destroy(sram->pool); + + return 0; +} + +#ifdef CONFIG_OF +static struct of_device_id sram_dt_ids[] = { + { .compatible = "sram" }, + { /* sentinel */ } +}; +#endif + +static struct platform_driver sram_driver = { + .driver = { + .name = "sram", + .of_match_table = of_match_ptr(sram_dt_ids), + }, + .probe = sram_probe, + .remove = __devexit_p(sram_remove), +}; + +module_platform_driver(sram_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Philipp Zabel, Pengutronix"); +MODULE_DESCRIPTION("Generic SRAM allocator driver"); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/9] ARM i.MX: Switch IRAM allocator to device tree initialization
Signed-off-by: Philipp Zabel --- arch/arm/plat-mxc/include/mach/iram.h |6 - arch/arm/plat-mxc/iram_alloc.c| 44 ++--- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/arch/arm/plat-mxc/include/mach/iram.h b/arch/arm/plat-mxc/include/mach/iram.h index 022690c..d5c863f 100644 --- a/arch/arm/plat-mxc/include/mach/iram.h +++ b/arch/arm/plat-mxc/include/mach/iram.h @@ -20,17 +20,11 @@ #ifdef CONFIG_IRAM_ALLOC -int __init iram_init(unsigned long base, unsigned long size); void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr); void iram_free(unsigned long dma_addr, unsigned int size); #else -static inline int __init iram_init(unsigned long base, unsigned long size) -{ - return -ENOMEM; -} - static inline void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) { return NULL; diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/plat-mxc/iram_alloc.c index 074c386..673deb4 100644 --- a/arch/arm/plat-mxc/iram_alloc.c +++ b/arch/arm/plat-mxc/iram_alloc.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include static unsigned long iram_phys_base; @@ -55,15 +57,26 @@ void iram_free(unsigned long addr, unsigned int size) } EXPORT_SYMBOL(iram_free); -int __init iram_init(unsigned long base, unsigned long size) +static int __devinit iram_probe(struct platform_device *pdev) { - iram_phys_base = base; + struct resource *res; + unsigned long size; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + if (iram_phys_base) + return -EBUSY; + + iram_phys_base = res->start; + size = resource_size(res); iram_pool = gen_pool_create(PAGE_SHIFT, -1); if (!iram_pool) return -ENOMEM; - gen_pool_add(iram_pool, base, size, -1); + gen_pool_add(iram_pool, res->start, size, -1); iram_virt_base = ioremap(iram_phys_base, size); if (!iram_virt_base) return -EIO; @@ -71,3 +84,28 @@ int __init iram_init(unsigned long base, unsigned long size) pr_debug("i.MX IRAM pool: %ld KB@0x%p\n", size / 1024, iram_virt_base); return 0; } + +static int __devexit iram_remove(struct platform_device *pdev) +{ + gen_pool_destroy(iram_pool); + iram_pool = NULL; + return 0; +} + +#ifdef CONFIG_OF +static struct of_device_id iram_dt_ids[] = { + { .compatible = "fsl,imx-iram" }, + { /* sentinel */ } +}; +#endif + +static struct platform_driver iram_driver = { + .driver = { + .name = "imx-iram", + .of_match_table = of_match_ptr(iram_dt_ids), + }, + .probe = iram_probe, + .remove = __devexit_p(iram_remove), +}; + +module_platform_driver(iram_driver); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 9/9] ARM i.MX: remove IRAM_ALLOC facility
A generic on-chip SRAM allocator driver can be used instead. Users of the iram_alloc/free API should convert to the genalloc API: - virt = iram_alloc(SIZE, &phys); + gen_pool_alloc(iram_pool, SIZE); + phys = gen_pool_virt_to_phys(iram_pool, virt); /* ... */ - iram_free(virt, SIZE); + gen_pool_free(iram_pool, virt, SIZE); Signed-off-by: Philipp Zabel --- arch/arm/plat-mxc/Kconfig |4 -- arch/arm/plat-mxc/Makefile|1 - arch/arm/plat-mxc/include/mach/iram.h | 35 -- arch/arm/plat-mxc/iram_alloc.c| 116 - 4 files changed, 156 deletions(-) delete mode 100644 arch/arm/plat-mxc/include/mach/iram.h delete mode 100644 arch/arm/plat-mxc/iram_alloc.c diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index baf9064..8e63f10 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -82,8 +82,4 @@ config IMX_HAVE_IOMUX_V1 config ARCH_MXC_IOMUX_V3 bool -config IRAM_ALLOC - bool - select GENERIC_ALLOCATOR - endif diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 6ac7200..bdf370f 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_MXC_AVIC) += avic.o obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o -obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o obj-$(CONFIG_MXC_ULPI) += ulpi.o obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o diff --git a/arch/arm/plat-mxc/include/mach/iram.h b/arch/arm/plat-mxc/include/mach/iram.h deleted file mode 100644 index d5c863f..000 --- a/arch/arm/plat-mxc/include/mach/iram.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -#include - -#ifdef CONFIG_IRAM_ALLOC - -void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr); -void iram_free(unsigned long dma_addr, unsigned int size); - -#else - -static inline void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) -{ - return NULL; -} - -static inline void iram_free(unsigned long base, unsigned long size) {} - -#endif diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/plat-mxc/iram_alloc.c deleted file mode 100644 index 343e96d..000 --- a/arch/arm/plat-mxc/iram_alloc.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static struct gen_pool *iram_pool; - -void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) -{ - unsigned long virt; - - if (!iram_pool) - return NULL; - - virt = gen_pool_alloc(iram_pool, size); - pr_debug("iram alloc - %dB@0x%lX\n", size, *dma_addr); - if (!virt) - return NULL; - - *dma_addr = gen_pool_virt_to_phys(iram_pool, virt); - return (void __iomem *)virt; -} -EXPORT_SYMBOL(iram_alloc); - -void iram_free(unsigned long addr, unsigned int size) -{ - if (!iram_pool) - return; - - gen_pool_free(iram_pool, addr, size); -} -EXPORT_SYMBOL(iram_free); - -static int __devinit iram_probe(struct platform_device *pdev) -{ - void __iomem *virt_base; - struct resource *res; - unsigned long size; - int ret; - - res = platform_get
[PATCH v2 5/9] genalloc: add a global pool list, allow to find pools by phys address
This patch keeps all created pools in a global list and adds two functions that allow to retrieve the gen_pool pointer from a known physical address and from a device tree node. Signed-off-by: Philipp Zabel --- include/linux/genalloc.h | 14 + lib/genalloc.c | 77 ++ 2 files changed, 91 insertions(+) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 5e98eeb..46ff435 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -33,6 +33,7 @@ * General purpose special memory pool descriptor. */ struct gen_pool { + struct list_head next_pool; /* pool in global list */ spinlock_t lock; struct list_head chunks;/* list of chunks in this pool */ int min_alloc_order;/* minimum allocation order */ @@ -78,4 +79,17 @@ extern void gen_pool_for_each_chunk(struct gen_pool *, void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); extern size_t gen_pool_avail(struct gen_pool *); extern size_t gen_pool_size(struct gen_pool *); +extern struct gen_pool *gen_pool_find_by_phys(phys_addr_t phys); + +#ifdef CONFIG_OF +struct device_node; +extern struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index); +#else +inline struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + return NULL; +} +#endif #endif /* __GENALLOC_H__ */ diff --git a/lib/genalloc.c b/lib/genalloc.c index 6bc04aa..df2d8f9 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -34,6 +34,11 @@ #include #include #include +#include +#include + +static LIST_HEAD(pools); +static DEFINE_SPINLOCK(list_lock); static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) { @@ -152,6 +157,9 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid) spin_lock_init(&pool->lock); INIT_LIST_HEAD(&pool->chunks); pool->min_alloc_order = min_alloc_order; + spin_lock(&list_lock); + list_add_rcu(&pool->next_pool, &pools); + spin_unlock(&list_lock); } return pool; } @@ -234,6 +242,9 @@ void gen_pool_destroy(struct gen_pool *pool) int order = pool->min_alloc_order; int bit, end_bit; + spin_lock(&list_lock); + list_del_rcu(&pool->next_pool); + spin_unlock(&list_lock); list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); list_del(&chunk->next_chunk); @@ -400,3 +411,69 @@ size_t gen_pool_size(struct gen_pool *pool) return size; } EXPORT_SYMBOL_GPL(gen_pool_size); + +/** + * gen_pool_find_by_phys - find a pool by physical start address + * @phys: physical address as added with gen_pool_add_virt + * + * Returns the pool that contains the chunk starting at phys, + * or NULL if not found. + */ +struct gen_pool *gen_pool_find_by_phys(phys_addr_t phys) +{ + struct gen_pool *pool, *found = NULL; + struct gen_pool_chunk *chunk; + + rcu_read_lock(); + list_for_each_entry_rcu(pool, &pools, next_pool) { + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { + if (phys == chunk->phys_addr) { + found = pool; + break; + } + } + } + rcu_read_unlock(); + + return found; +} +EXPORT_SYMBOL_GPL(gen_pool_find_by_phys); + +#ifdef CONFIG_OF +/** + * of_get_named_gen_pool - find a pool by the physical address in + * @np: device node + * + * Returns the pool that contains the chunk starting at the physical + * address of the np device node, or NULL if not found. + */ +struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + struct property *prop; + const __be32 *list; + int size; + phandle phandle; + struct device_node *np_pool; + const u32 *reg; + u64 addr; + + prop = of_find_property(np, propname, &size); + if (!prop) + return NULL; + list = prop->value; + size /= sizeof(*list); + phandle = be32_to_cpup(list); + np_pool = of_find_node_by_phandle(phandle); + if (!np_pool) + return NULL; + reg = of_get_property(np_pool, "reg", NULL); + if (!reg) + return NULL; + addr = of_translate_address(np_pool, reg); + if (addr == OF_BAD_ADDR) + return NULL; + return gen_pool_find_by_phys((phys_addr_t) addr); +} +EXPORT_SYMBOL_GPL(of_get_named_gen_pool); +#endif /* CONFIG_OF */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsu
[PATCH v2 4/9] iram_alloc: store the virt and phys mem address in gen_pool chunks
This improves the symmetry of iram_alloc and iram_free in that iram_free has to be called with the virtual address now. Also, gen_pool_virt_to_phys is now functional. Signed-off-by: Philipp Zabel --- arch/arm/plat-mxc/iram_alloc.c | 39 ++- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/plat-mxc/iram_alloc.c index 673deb4..343e96d 100644 --- a/arch/arm/plat-mxc/iram_alloc.c +++ b/arch/arm/plat-mxc/iram_alloc.c @@ -26,25 +26,22 @@ #include #include -static unsigned long iram_phys_base; -static void __iomem *iram_virt_base; static struct gen_pool *iram_pool; -static inline void __iomem *iram_phys_to_virt(unsigned long p) -{ - return iram_virt_base + (p - iram_phys_base); -} - void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) { + unsigned long virt; + if (!iram_pool) return NULL; - *dma_addr = gen_pool_alloc(iram_pool, size); + virt = gen_pool_alloc(iram_pool, size); pr_debug("iram alloc - %dB@0x%lX\n", size, *dma_addr); - if (!*dma_addr) + if (!virt) return NULL; - return iram_phys_to_virt(*dma_addr); + + *dma_addr = gen_pool_virt_to_phys(iram_pool, virt); + return (void __iomem *)virt; } EXPORT_SYMBOL(iram_alloc); @@ -59,29 +56,37 @@ EXPORT_SYMBOL(iram_free); static int __devinit iram_probe(struct platform_device *pdev) { + void __iomem *virt_base; struct resource *res; unsigned long size; + int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -EINVAL; - if (iram_phys_base) + if (iram_pool) return -EBUSY; - iram_phys_base = res->start; size = resource_size(res); + virt_base = devm_ioremap(&pdev->dev, res->start, size); + if (!virt_base) + return -ENOMEM; + iram_pool = gen_pool_create(PAGE_SHIFT, -1); if (!iram_pool) return -ENOMEM; - gen_pool_add(iram_pool, res->start, size, -1); - iram_virt_base = ioremap(iram_phys_base, size); - if (!iram_virt_base) - return -EIO; + ret = gen_pool_add_virt(iram_pool, (unsigned long)virt_base, + res->start, size, -1); + if (ret < 0) { + gen_pool_destroy(iram_pool); + iram_pool = NULL; + return ret; + } - pr_debug("i.MX IRAM pool: %ld KB@0x%p\n", size / 1024, iram_virt_base); + pr_debug("i.MX IRAM pool: %ld KB@0x%p\n", size / 1024, virt_base); return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 0/9] Add device tree support for on-chip SRAM
These patches add support to configure on-chip SRAM via device-tree node and to obtain the resulting genalloc pool from a phandle pointing at the node. This allows drivers to allocate SRAM with the genalloc API without hard-coding the genalloc pool address. The on-chip SRAM on i.MX53 and i.MX6q is registered via device tree and changed to use the simple generic SRAM driver: ocram: ocram@0090 { compatible = "fsl,imx-ocram", "sram"; reg = <0x0090 0x3f000>; }; A driver that needs to allocate SRAM buffers, like the video processing unit on i.MX53, can retrieve the genalloc pool from a phandle in the device tree using of_get_named_gen_pool(node, "iram", 0) from patch 5: vpu@63ff4000 { /* ... */ iram = <&ocram>; }; Changes since v1: - Added a generic SRAM driver in drivers/misc that does nothing but request/ioremap its given memory region and serve it via the genalloc API. - Renamed the i.MX device tree nodes from "iram" to "ocram". regards Philipp --- arch/arm/boot/dts/imx53.dtsi |5 ++ arch/arm/boot/dts/imx6q.dtsi |5 ++ arch/arm/plat-mxc/Kconfig |4 -- arch/arm/plat-mxc/Makefile|1 - arch/arm/plat-mxc/include/mach/iram.h | 41 - arch/arm/plat-mxc/iram_alloc.c| 73 --- drivers/misc/Kconfig |8 +++ drivers/misc/Makefile |1 + drivers/misc/sram.c | 105 + include/linux/genalloc.h | 14 + lib/genalloc.c| 77 11 files changed, 215 insertions(+), 119 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 2/9] ARM i.MX53: Add OCRAM to device tree
Signed-off-by: Philipp Zabel --- - Renamed "iram" to "ocram" as it appears in the processor reference manuals. --- arch/arm/boot/dts/imx53.dtsi |5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index cd37165..5da342a 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -337,5 +337,10 @@ status = "disabled"; }; }; + + ocram@f800 { + compatible = "fsl,imx-ocram"; + reg = <0xf800 0x2>; + }; }; }; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 3/9] ARM i.MX6: Add OCRAM to device tree
Signed-off-by: Philipp Zabel --- Changes since v1: - Renamed "iram" to "ocram" as it appears in the processor reference manuals. --- arch/arm/boot/dts/imx6q.dtsi |5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index fd57079..9cb0b50 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -111,6 +111,11 @@ status = "disabled"; }; + ocram@0090 { + compatible = "fsl,imx-ocram"; + reg = <0x0090 0x3f000>; + }; + timer@00a00600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x00a00600 0x20>; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 0/9] Add device tree support for on-chip SRAM
Hi Shawn, Am Montag, den 03.09.2012, 09:53 +0800 schrieb Shawn Guo: > I do not understand the point of introducing those imx patches, 1 ~ 4 > and 7, 8. They are all unnecessary churns to me. IMO, 4 patches are > enough. > > * genalloc: add a global pool list, allow to find pools by phys address > * misc: Generic on-chip SRAM allocation driver > * ARM i.MX: remove IRAM_ALLOC facility > * ARM: dts: add sram for imx53 and imx6q > > Regards, > Shawn Thanks, I thought that first making the iram_alloc API work would decouple this a bit from the coda vpu patches that depend on sram support on imx53/6q. I'll work in your comments and reduce the patch count as you propose. regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 4/4] ARM i.MX: remove IRAM_ALLOC facility
A generic on-chip SRAM allocator driver can be used instead. Users of the iram_alloc/free API should convert to the genalloc API: - virt = iram_alloc(SIZE, &phys); + gen_pool_alloc(iram_pool, SIZE); + phys = gen_pool_virt_to_phys(iram_pool, virt); /* ... */ - iram_free(virt, SIZE); + gen_pool_free(iram_pool, virt, SIZE); Signed-off-by: Philipp Zabel --- arch/arm/plat-mxc/Kconfig |4 -- arch/arm/plat-mxc/Makefile|1 - arch/arm/plat-mxc/include/mach/iram.h | 41 -- arch/arm/plat-mxc/iram_alloc.c| 73 - 4 files changed, 119 deletions(-) delete mode 100644 arch/arm/plat-mxc/include/mach/iram.h delete mode 100644 arch/arm/plat-mxc/iram_alloc.c diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index baf9064..8e63f10 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -82,8 +82,4 @@ config IMX_HAVE_IOMUX_V1 config ARCH_MXC_IOMUX_V3 bool -config IRAM_ALLOC - bool - select GENERIC_ALLOCATOR - endif diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 6ac7200..bdf370f 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_MXC_AVIC) += avic.o obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o -obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o obj-$(CONFIG_MXC_ULPI) += ulpi.o obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o diff --git a/arch/arm/plat-mxc/include/mach/iram.h b/arch/arm/plat-mxc/include/mach/iram.h deleted file mode 100644 index 022690c..000 --- a/arch/arm/plat-mxc/include/mach/iram.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -#include - -#ifdef CONFIG_IRAM_ALLOC - -int __init iram_init(unsigned long base, unsigned long size); -void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr); -void iram_free(unsigned long dma_addr, unsigned int size); - -#else - -static inline int __init iram_init(unsigned long base, unsigned long size) -{ - return -ENOMEM; -} - -static inline void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) -{ - return NULL; -} - -static inline void iram_free(unsigned long base, unsigned long size) {} - -#endif diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/plat-mxc/iram_alloc.c deleted file mode 100644 index 074c386..000 --- a/arch/arm/plat-mxc/iram_alloc.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -static unsigned long iram_phys_base; -static void __iomem *iram_virt_base; -static struct gen_pool *iram_pool; - -static inline void __iomem *iram_phys_to_virt(unsigned long p) -{ - return iram_virt_base + (p - iram_phys_base); -} - -void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) -{ - if (!iram_pool) - return NULL; - - *dma_addr = gen_pool_alloc(iram_pool, size); - pr_debug("iram alloc - %dB@0x%lX\n", size, *dma_addr); - if (!*dma_addr) - return NULL; - return iram_phys_to_virt(*dma_addr); -} -EXPORT_SYMBOL(iram_alloc); - -void iram_free(unsigned long addr, unsigned int size) -{ - if (!iram_pool) - return; - -
[PATCH v3 3/4] ARM: dts: add sram for imx53 and imx6q
Signed-off-by: Philipp Zabel --- arch/arm/boot/dts/imx53.dtsi |5 + arch/arm/boot/dts/imx6q.dtsi |5 + 2 files changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index cd37165..2767a92 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -337,5 +337,10 @@ status = "disabled"; }; }; + + ocram: ocram@f800 { + compatible = "fsl,imx-ocram", "sram"; + reg = <0xf800 0x2>; + }; }; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index fd57079..1e463c4 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -111,6 +111,11 @@ status = "disabled"; }; + ocram: ocram@0090 { + compatible = "fsl,imx-ocram", "sram"; + reg = <0x0090 0x3f000>; + }; + timer@00a00600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x00a00600 0x20>; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 1/4] genalloc: add a global pool list, allow to find pools by phys address
This patch keeps all created pools in a global list and adds two functions that allow to retrieve the gen_pool pointer from a known physical address and from a device tree node. Signed-off-by: Philipp Zabel --- Changes since v2: - Moved struct device_node declaration out of #ifdef CONFIG_OF. - Simplified of_get_named_gen_pool using of_parse_phandle and of_address_to_resource. --- include/linux/genalloc.h | 14 ++ lib/genalloc.c | 67 ++ 2 files changed, 81 insertions(+) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 5e98eeb..d498c43 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -33,6 +33,7 @@ * General purpose special memory pool descriptor. */ struct gen_pool { + struct list_head next_pool; /* pool in global list */ spinlock_t lock; struct list_head chunks;/* list of chunks in this pool */ int min_alloc_order;/* minimum allocation order */ @@ -78,4 +79,17 @@ extern void gen_pool_for_each_chunk(struct gen_pool *, void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); extern size_t gen_pool_avail(struct gen_pool *); extern size_t gen_pool_size(struct gen_pool *); +extern struct gen_pool *gen_pool_find_by_phys(phys_addr_t phys); + +struct device_node; +#ifdef CONFIG_OF +extern struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index); +#else +inline struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + return NULL; +} +#endif #endif /* __GENALLOC_H__ */ diff --git a/lib/genalloc.c b/lib/genalloc.c index 6bc04aa..90699ac 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -34,6 +34,11 @@ #include #include #include +#include +#include + +static LIST_HEAD(pools); +static DEFINE_SPINLOCK(list_lock); static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) { @@ -152,6 +157,9 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid) spin_lock_init(&pool->lock); INIT_LIST_HEAD(&pool->chunks); pool->min_alloc_order = min_alloc_order; + spin_lock(&list_lock); + list_add_rcu(&pool->next_pool, &pools); + spin_unlock(&list_lock); } return pool; } @@ -234,6 +242,9 @@ void gen_pool_destroy(struct gen_pool *pool) int order = pool->min_alloc_order; int bit, end_bit; + spin_lock(&list_lock); + list_del_rcu(&pool->next_pool); + spin_unlock(&list_lock); list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); list_del(&chunk->next_chunk); @@ -400,3 +411,59 @@ size_t gen_pool_size(struct gen_pool *pool) return size; } EXPORT_SYMBOL_GPL(gen_pool_size); + +/** + * gen_pool_find_by_phys - find a pool by physical start address + * @phys: physical address as added with gen_pool_add_virt + * + * Returns the pool that contains the chunk starting at phys, + * or NULL if not found. + */ +struct gen_pool *gen_pool_find_by_phys(phys_addr_t phys) +{ + struct gen_pool *pool, *found = NULL; + struct gen_pool_chunk *chunk; + + rcu_read_lock(); + list_for_each_entry_rcu(pool, &pools, next_pool) { + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { + if (phys == chunk->phys_addr) { + found = pool; + break; + } + } + } + rcu_read_unlock(); + + return found; +} +EXPORT_SYMBOL_GPL(gen_pool_find_by_phys); + +#ifdef CONFIG_OF +/** + * of_get_named_gen_pool - find a pool by phandle property + * @np: device node + * @propname: property name containing phandle(s) + * @index: index into the phandle array + * + * Returns the pool that contains the chunk starting at the physical + * address of the device tree node pointed at by the phandle property, + * or NULL if not found. + */ +struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + struct device_node *np_pool; + struct resource res; + int ret; + + np_pool = of_parse_phandle(np, propname, index); + if (!np_pool) + return NULL; + ret = of_address_to_resource(np_pool, 0, &res); + if (ret < 0) + return NULL; + return gen_pool_find_by_phys((phys_addr_t) res.start); +} +EXPORT_SYMBOL_GPL(of_get_named_gen_pool); +#endif /* CONFIG_OF */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 2/4] misc: Generic on-chip SRAM allocation driver
This driver requests and remaps a memory region as configured in the device tree. It serves memory from this region via the genalloc API. Other drivers can retrieve the genalloc pool from a phandle pointing to this drivers' device node in the device tree. Signed-off-by: Philipp Zabel --- Changes since v2: - Return -EADDRNOTAVAIL if devm_request_and_ioremap fails. --- drivers/misc/Kconfig |9 + drivers/misc/Makefile |1 + drivers/misc/sram.c | 105 + 3 files changed, 115 insertions(+) create mode 100644 drivers/misc/sram.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 98a442d..9a3395f 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -509,6 +509,15 @@ config USB_SWITCH_FSA9480 stereo and mono audio, video, microphone and UART data to use a common connector port. +config SRAM + bool "Generic on-chip SRAM driver" + depends on HAS_IOMEM + select GENERIC_ALLOCATOR + help + This driver allows to declare a memory region to be managed + by the genalloc API. It is supposed to be used for small + on-chip SRAM areas found on many ARM SoCs. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b88df7a..ccc759a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -50,3 +50,4 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_INTEL_MEI)+= mei/ +obj-$(CONFIG_SRAM) += sram.o diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c new file mode 100644 index 000..d6e1230 --- /dev/null +++ b/drivers/misc/sram.c @@ -0,0 +1,105 @@ +/* + * Generic on-chip SRAM allocation driver + * + * Copyright (C) 2012 Philipp Zabel, Pengutronix + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct sram_dev { + struct gen_pool *pool; +}; + +static int __devinit sram_probe(struct platform_device *pdev) +{ + void __iomem *virt_base; + struct sram_dev *sram; + struct resource *res; + unsigned long size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + size = resource_size(res); + + virt_base = devm_request_and_ioremap(&pdev->dev, res); + if (!virt_base) + return -EADDRNOTAVAIL; + + sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL); + if (!sram) + return -ENOMEM; + + sram->pool = gen_pool_create(PAGE_SHIFT, -1); + if (!sram->pool) + return -ENOMEM; + + ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base, + res->start, size, -1); + if (ret < 0) { + gen_pool_destroy(sram->pool); + return ret; + } + + platform_set_drvdata(pdev, sram); + + dev_dbg(&pdev->dev, "SRAM pool: %ld KiB @ 0x%p\n", size / 1024, virt_base); + + return 0; +} + +static int __devexit sram_remove(struct platform_device *pdev) +{ + struct sram_dev *sram = platform_get_drvdata(pdev); + + if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool)) + dev_dbg(&pdev->dev, "removed while SRAM allocated\n"); + + gen_pool_destroy(sram->pool); + + return 0; +} + +#ifdef CONFIG_OF +static struct of_device_id sram_dt_ids[] = { + { .compatible = "sram" }, + { /* sentinel */ } +}; +#endif + +static struct platform_driver sram_driver = { + .driver = { + .name = "sram", + .of_match_table = of_match_ptr(sram_dt_ids), + }, + .probe = sram_probe, + .remove = __devexit_p(sram_remove), +}; + +module_platform_driver(sram_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Philipp Zabel, Pengutronix"); +MODULE_DESCRIPTION("Generic SRAM
[PATCH v3 0/4] Add device tree support for on-chip SRAM
These patches add support to configure on-chip SRAM via device-tree node and to obtain the resulting genalloc pool from a phandle pointing at the node. This allows drivers to allocate SRAM with the genalloc API without hard-coding the genalloc pool address. The on-chip SRAM on i.MX53 and i.MX6q is registered via device tree and changed to use the simple generic SRAM driver: ocram: ocram@0090 { compatible = "fsl,imx-ocram", "sram"; reg = <0x0090 0x3f000>; }; A driver that needs to allocate SRAM buffers, like the video processing unit on i.MX53, can retrieve the genalloc pool from a phandle in the device tree using of_get_named_gen_pool(node, "iram", 0) from patch 5: vpu@63ff4000 { /* ... */ iram = <&ocram>; }; Changes since v2, as per Shawn's suggestions: - Moved struct device_node declaration out of #ifdef CONFIG_OF. - Simplified of_get_named_gen_pool using of_parse_phandle and of_address_to_resource. - Return -EADDRNOTAVAIL if devm_request_and_ioremap fails. - Squashed i.MX changes together. regards Philipp --- arch/arm/boot/dts/imx53.dtsi |5 ++ arch/arm/boot/dts/imx6q.dtsi |5 ++ arch/arm/plat-mxc/Kconfig |4 -- arch/arm/plat-mxc/Makefile|1 - arch/arm/plat-mxc/include/mach/iram.h | 41 - arch/arm/plat-mxc/iram_alloc.c| 73 --- drivers/misc/Kconfig |9 +++ drivers/misc/Makefile |1 + drivers/misc/sram.c | 105 + include/linux/genalloc.h | 14 + lib/genalloc.c| 67 + 11 files changed, 206 insertions(+), 119 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
FLUSH/FUA documentation & code discrepancy
Hi, I think commit 1e87901e18 was wrong. Starting with that commit the REQ_FLUSH and REQ_FUA bits get stripped away if the queue does not advertise REQ_FLUSH or REQ_FUA support. But the REQ_FLUSH bit is also tested for when not merging requests (blk_queue_bio()) or when it comes to the elevator (blk_flush_plug_list()). So, since this patch the elevator reorders write requests on queues that do not have REQ_FLUSH or REQ_FUA set. While on queues that have REQ_FLUSH or REQ_FUA set, the elevator does not reorder writes across FLUSHes. The Documentation/block/writeback_cache_control.txt file says: --snip-- Implementation details for filesystems -- Filesystems can simply set the REQ_FLUSH and REQ_FUA bits and do not have to worry if the underlying devices need any explicit cache flushing and how the Forced Unit Access is implemented. The REQ_FLUSH and REQ_FUA flags may both be set on a single bio. --snap-- I have the impression every file system lets IO drain, and issues a flush afterwards with the blkdev_issue_flush() function. BTW that function turns into a non-obvious no-op as soon as the queue does not have the REQ_FUA or REQ_FLUSH bits set. It does not look like it is a no-op by intention. The file systems seem to be all fine, only in DRBD we have a mode were we depend on REQ_FUA/REQ_FLUSH requests being real boundaries for reordering of writes. This is broken since the mentioned commit as we recently found out. I suggest that either this commit gets reverted, or the documentation is updated. I am ready to prepare such a patch, but I need directions how it should be fixed. Best regards, Phil -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Drbd-dev] FLUSH/FUA documentation & code discrepancy
> Currently, FLUSH/FUA doesn't enforce any ordering requirement. File > systems are responsible for draining all writes which have to happen > before and not issue further writes which should come after. Ok. That is a clear statement. So we will do it that way. The "Currently" in you statement, suggests that there might be something more mighty in the future. Is that true? We are looking for a method that allows us to submit some writes, then an IO-barrier, and then further writes. Best, Phil -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] drbd-8.3 updates
Hi Jens, Please consider to pull these changes for the 3.7 merge window. Best, Phil The following changes since commit a0d271cbfed1dd50278c6b06bead3d00ba0a88f9: Linux 3.6 (2012-09-30 16:47:46 -0700) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens for you to fetch changes up to a783d564a1badbb87b3f96aa8df581ed4167a9c9: drbd: log request sector offset and size for IO errors (2012-10-02 14:52:24 +0200) Lars Ellenberg (9): drbd: introduce stop-sector to online verify drbd: change error cleanup goto for failed kobject_init_and_add drbd: panic on delayed completion of aborted requests drbd: fix potential deadlock during bitmap (re-)allocation drbd: a few more GFP_KERNEL -> GFP_NOIO drbd: wait for meta data IO completion even with failed disk, unless force-detached drbd: prepare for more than 32 bit flags drbd: always write bitmap on detach drbd: log request sector offset and size for IO errors Philipp Reisner (6): drbd: Add a drbd directory to sysfs drbd: expose the data generation identifiers via sysfs drbd: Protect accesses to the uuid set with a spinlock drbd: Fix a potential issue with the DISCARD_CONCURRENT flag drbd: Avoid NetworkFailure state during disconnect drbd: Remove dead code drivers/block/drbd/Makefile|1 + drivers/block/drbd/drbd_actlog.c | 19 ++-- drivers/block/drbd/drbd_bitmap.c | 24 ++--- drivers/block/drbd/drbd_int.h | 112 +-- drivers/block/drbd/drbd_main.c | 175 drivers/block/drbd/drbd_nl.c | 109 +- drivers/block/drbd/drbd_proc.c | 14 ++- drivers/block/drbd/drbd_receiver.c | 147 -- drivers/block/drbd/drbd_req.c | 43 ++--- drivers/block/drbd/drbd_sysfs.c| 86 ++ drivers/block/drbd/drbd_worker.c | 87 ++ include/linux/drbd.h |4 +- include/linux/drbd_nl.h|1 + 13 files changed, 571 insertions(+), 251 deletions(-) create mode 100644 drivers/block/drbd/drbd_sysfs.c -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] drbd-8.3 updates
> Not pulled. Two reasons: > > - It's late (in the merge window) > - and it's not based off my for-3.7/drivers branch, hence I get a ton of > unrelated changes with a pull into that branch. Hi Jens, I can rebase it for you in a few hours. Would influence this your decission? Best, Phil -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] drbd-8.3 updates
Am Mittwoch, 3. Oktober 2012, 11:24:09 schrieben Sie: > > Not pulled. Two reasons: > > > > - It's late (in the merge window) > > - and it's not based off my for-3.7/drivers branch, hence I get a ton of > > > > unrelated changes with a pull into that branch. > > Hi Jens, > > I can rebase it for you in a few hours. Would influence this your decission? > Hi Jens, Is there a convenient way for me to find our when it is the right time to send pull requests your way? (i.e. a notification when you create your for-3.x/drivers branch) Rebasing it on your drivers tree was trivial, here is the updated pull request: The following changes since commit fab74e7a8f0f8d0af2356c28aa60d55f9e6f5f8b: loop: Make explicit loop device destruction lazy (2012-09-28 10:42:23 +0200) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens for you to fetch changes up to 61e8114a682b0e868696f8363ed03e5fd4c750d1: drbd: log request sector offset and size for IO errors (2012-10-03 11:54:45 +0200) Lars Ellenberg (9): drbd: introduce stop-sector to online verify drbd: change error cleanup goto for failed kobject_init_and_add drbd: panic on delayed completion of aborted requests drbd: fix potential deadlock during bitmap (re-)allocation drbd: a few more GFP_KERNEL -> GFP_NOIO drbd: wait for meta data IO completion even with failed disk, unless force-detached drbd: prepare for more than 32 bit flags drbd: always write bitmap on detach drbd: log request sector offset and size for IO errors Philipp Reisner (6): drbd: Add a drbd directory to sysfs drbd: expose the data generation identifiers via sysfs drbd: Protect accesses to the uuid set with a spinlock drbd: Fix a potential issue with the DISCARD_CONCURRENT flag drbd: Avoid NetworkFailure state during disconnect drbd: Remove dead code drivers/block/drbd/Makefile|1 + drivers/block/drbd/drbd_actlog.c | 19 ++-- drivers/block/drbd/drbd_bitmap.c | 24 ++--- drivers/block/drbd/drbd_int.h | 112 +-- drivers/block/drbd/drbd_main.c | 175 drivers/block/drbd/drbd_nl.c | 109 +- drivers/block/drbd/drbd_proc.c | 14 ++- drivers/block/drbd/drbd_receiver.c | 147 -- drivers/block/drbd/drbd_req.c | 43 ++--- drivers/block/drbd/drbd_sysfs.c| 86 ++ drivers/block/drbd/drbd_worker.c | 87 ++ include/linux/drbd.h |4 +- include/linux/drbd_nl.h|1 + 13 files changed, 571 insertions(+), 251 deletions(-) create mode 100644 drivers/block/drbd/drbd_sysfs.c Best, Phil -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] drbd-8.3 updates
> Thanks, one question before this is pulled in: > > Philipp Reisner (6): > > drbd: Add a drbd directory to sysfs > > drbd: expose the data generation identifiers via sysfs > > What are these? It's sitting in /sys/block//drbd/, I don't see any > documentation or justification for that. > > Why isn't it off in debugfs or similar instead? The long-time goal is to get rid of the /proc/drbd virtual file, and present the information that was there in a more structured way in /sys. This patch adds a very first step into that direction. Later we intend to have here things like the connections state, device roles, statistics counters there. When coming up with the layout we used the sysfs presence of software raid as example. I have removed it from this pull-request, so that there is more time for consideration before the next merge window. The following changes since commit fab74e7a8f0f8d0af2356c28aa60d55f9e6f5f8b: loop: Make explicit loop device destruction lazy (2012-09-28 10:42:23 +0200) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens for you to fetch changes up to 56a2dabd4d953b70c4630387368d79d6d1625c1d: drbd: log request sector offset and size for IO errors (2012-10-03 15:46:04 +0200) Lars Ellenberg (8): drbd: introduce stop-sector to online verify drbd: panic on delayed completion of aborted requests drbd: fix potential deadlock during bitmap (re-)allocation drbd: a few more GFP_KERNEL -> GFP_NOIO drbd: wait for meta data IO completion even with failed disk, unless force-detached drbd: prepare for more than 32 bit flags drbd: always write bitmap on detach drbd: log request sector offset and size for IO errors Philipp Reisner (4): drbd: Protect accesses to the uuid set with a spinlock drbd: Fix a potential issue with the DISCARD_CONCURRENT flag drbd: Avoid NetworkFailure state during disconnect drbd: Remove dead code drivers/block/drbd/drbd_actlog.c | 19 ++-- drivers/block/drbd/drbd_bitmap.c | 24 ++--- drivers/block/drbd/drbd_int.h | 108 +-- drivers/block/drbd/drbd_main.c | 170 drivers/block/drbd/drbd_nl.c | 74 +--- drivers/block/drbd/drbd_proc.c | 14 ++- drivers/block/drbd/drbd_receiver.c | 147 --- drivers/block/drbd/drbd_req.c | 43 ++--- drivers/block/drbd/drbd_worker.c | 87 ++ include/linux/drbd.h |4 +- include/linux/drbd_nl.h|1 + 11 files changed, 451 insertions(+), 240 deletions(-) Best, Phil -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 0/6] uio_pruss cleanup and platform support
Hi Matt, On 10/3/12, Matt Porter wrote: > This series enables uio_pruss on DA850 and removes use of the > private SRAM API by the driver. The driver previously was not > enabled by any platform and the private SRAM API was accessing > an invalid SRAM bank. have you seen my SRAM patch series at https://lkml.org/lkml/2012/9/7/281 "Add device tree support for on-chip SRAM" ? I think the generic SRAM/genalloc driver (https://lkml.org/lkml/2012/9/7/282) could be useful to map the L3RAM on Davinci. With the gen_pool lookup patch (https://lkml.org/lkml/2012/9/7/284) the uio_pruss driver could then use the gen_pool_find_by_phys() (or of_get_named_gen_pool() for initialization from device tree) to retrieve the struct gen_pool*. This way you could avoid handing it over via platform data and you could get rid of arch/arm/mach-davinci/{sram.c,include/mach/sram.h} completely. regards Philipp -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 0/6] uio_pruss cleanup and platform support
On Thu, Oct 04, 2012 at 08:42:53AM -0400, Matt Porter wrote: > > I think the generic SRAM/genalloc driver > > (https://lkml.org/lkml/2012/9/7/282) > > could be useful to map the L3RAM on Davinci. > > With the gen_pool lookup patch (https://lkml.org/lkml/2012/9/7/284) the > > uio_pruss driver could then use the gen_pool_find_by_phys() (or > > of_get_named_gen_pool() for initialization from device tree) to > > retrieve the struct gen_pool*. > > > > This way you could avoid handing it over via platform data and you could > > get rid of arch/arm/mach-davinci/{sram.c,include/mach/sram.h} completely. > > I did miss the gen_pool_find_by_phys() call in that series. That does > look useful. I actually mentioned your series in an earlier posting > since I like it, That I did miss. > but since the initialization of the driver was inherently > tied to DT it's not usable for DaVinci that's just starting to convert > to DT and needs !DT support as well. There should be no dependency on DT in the sram driver. It just requests and remaps the first given iomem resource and creates a gen_pool from that. This should work just as well for the !DT case. Maybe it's just my choice of patch series subject gave you that impression? If there's a real issue for !DT, I should fix it. > I do see it moving to your driver exclusively, but I wanted to make this > series focused on only getting rid of the private SRAM API using the > existing pdata framework that's already there. I think once > gen_pool_find_by_phys() goes upstream we can switch to that and get the > address from a resource in the !DT case. I guess we should see if Sekhar > would like to see this happen in two steps or just have us depend on > the gen_pool_find_by_phys() patch now. Thanks, I'm glad you are aware of the sram driver and consider it useful. > BTW, I was going to post a patch for your driver to allow > configurability of the allocation order, but have been busy with other > things. We'll eventually need that when switching to it as the > hardcoded page size order isn't going to work for all cases. Good point. regards Philipp -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 0/6] uio_pruss cleanup and platform support
On Thu, Oct 04, 2012 at 09:54:33AM -0400, Matt Porter wrote: > *sigh*, I see now. I looked at v2 and got wrapped up in the DT use case > and missed your platform device support. I think it will work just fine > for us to use in a "phase 2" of this work, replacing the backend of > davinci sram allocation with this as Sekhar seems to be open to. > > > > I do see it moving to your driver exclusively, but I wanted to make this > > > series focused on only getting rid of the private SRAM API using the > > > existing pdata framework that's already there. I think once > > > gen_pool_find_by_phys() goes upstream we can switch to that and get the > > > address from a resource in the !DT case. I guess we should see if Sekhar > > > would like to see this happen in two steps or just have us depend on > > > the gen_pool_find_by_phys() patch now. > > > > Thanks, I'm glad you are aware of the sram driver and consider it useful. > > > > > BTW, I was going to post a patch for your driver to allow > > > configurability of the allocation order, but have been busy with other > > > things. We'll eventually need that when switching to it as the > > > hardcoded page size order isn't going to work for all cases. > > > > Good point. > > I think this is the only blocker to DaVinci adopting it once it goes > upstream. I can add a patch in your driver thread if that helps. Yes, that would be welcome. regards Philipp -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 2/6] misc: Generic on-chip SRAM allocation driver
Am Donnerstag, den 04.10.2012, 11:25 -0400 schrieb Matt Porter: > On Fri, Sep 07, 2012 at 02:43:44PM +0200, Philipp Zabel wrote: > > This driver requests and remaps a memory region as configured in the > > device tree. It serves memory from this region via the genalloc API. > > > > Other drivers can retrieve the genalloc pool from a phandle pointing > > to this drivers' device node in the device tree. > > > > > + sram->pool = gen_pool_create(PAGE_SHIFT, -1); > > + if (!sram->pool) > > + return -ENOMEM; > > As mentioned in the uio_pruss/genalloc discussion, removing the > hardcoded minimum allocation order will allow this to be used for > a number of other cases. The most notable is moving mach-davinci/ > off of its own genalloc-based SRAM arch driver. Some of the davinci > SoCs have very small SRAMs and need the ability to allocate a smaller > chunk. > > Here's a build-tested patch to add this option: Thank you, > From 6eced8c31eba2f86e72e854cf404d8f58fbeba85 Mon Sep 17 00:00:00 2001 > From: Matt Porter > Date: Thu, 4 Oct 2012 11:08:02 -0400 > Subject: [PATCH] misc: sram: add support for configurable allocation order > > Adds support for setting the genalloc pool's minimum allocation > order via DT or platform data. The allocation order is optional > for both the DT property and platform data case. If it is not > present then the order defaults to PAGE_SHIFT to preserve the > current behavior. > > Signed-off-by: Matt Porter Tested-by: Philipp Zabel > --- > Documentation/devicetree/bindings/misc/sram.txt | 12 ++- > drivers/misc/sram.c | 14 - > include/linux/platform_data/sram.h | 25 > +++ > 3 files changed, 49 insertions(+), 2 deletions(-) > create mode 100644 include/linux/platform_data/sram.h > > diff --git a/Documentation/devicetree/bindings/misc/sram.txt > b/Documentation/devicetree/bindings/misc/sram.txt > index b64136c..b1705ec 100644 > --- a/Documentation/devicetree/bindings/misc/sram.txt > +++ b/Documentation/devicetree/bindings/misc/sram.txt > @@ -8,10 +8,20 @@ Required properties: > > - reg : SRAM iomem address range > > -Example: > +Optional properties: > + > +- alloc-order : Minimum allocation order for the SRAM pool > + > +Examples: > + > +sram: sram@5c00 { > + compatible = "sram"; > + reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ > +}; > > sram: sram@5c00 { > compatible = "sram"; > reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ > + alloc-order = <9>; /* Minimum 512 byte allocation */ > }; > > diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c > index 7a363f2..3bf8ed3 100644 > --- a/drivers/misc/sram.c > +++ b/drivers/misc/sram.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > struct sram_dev { > struct gen_pool *pool; > @@ -37,6 +38,7 @@ static int __devinit sram_probe(struct platform_device > *pdev) > struct sram_dev *sram; > struct resource *res; > unsigned long size; > + u32 alloc_order = PAGE_SHIFT; > int ret; > > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > @@ -53,7 +55,17 @@ static int __devinit sram_probe(struct platform_device > *pdev) > if (!sram) > return -ENOMEM; > > - sram->pool = gen_pool_create(PAGE_SHIFT, -1); > + if (pdev->dev.of_node) > + of_property_read_u32(pdev->dev.of_node, > + "alloc-order", &alloc_order); > + else > + if (pdev->dev.platform_data) { > + struct sram_pdata *pdata = pdev->dev.platform_data; > + if (pdata->alloc_order) > + alloc_order = pdata->alloc_order; > + } > + > + sram->pool = gen_pool_create(alloc_order, -1); > if (!sram->pool) > return -ENOMEM; > > diff --git a/include/linux/platform_data/sram.h > b/include/linux/platform_data/sram.h > new file mode 100644 > index 000..e17bdaa > --- /dev/null > +++ b/include/linux/platform_data/sram.h > @@ -0,0 +1,25 @@ > +/* > + * include/linux/platform_data/sram.h > + * > + * Platform data for generic sram driver > + * > + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Pu
Re: [GIT PULL] 4 fixes for drbd
> > Can you rebase this against for-3.8/drivers? Thanks. Hi Jens, One of these changes fixes a regression that was introduced in the last merge window. Please consider to pull this single commit. (I will rebase the other 3 commit on for-3.8/drivers) The following changes since commit a13c29ddf73d3be4fbb2b1bbced64014986cd87a: Jens Axboe (1): Merge branch 'for-jens' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/linux-block into for-3.7/drivers are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens Lars Ellenberg (1): drbd: fix regression: potential NULL pointer dereference drivers/block/drbd/drbd_int.h |5 + drivers/block/drbd/drbd_main.c |8 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] 4 fixes for drbd
Am Montag, 5. November 2012, 15:43:28 schrieb Jens Axboe: > On 2012-11-05 15:35, Philipp Reisner wrote: > >> Can you rebase this against for-3.8/drivers? Thanks. > > > > Hi Jens, > > > > One of these changes fixes a regression that was introduced in the last > > merge window. Please consider to pull this single commit. > > (I will rebase the other 3 commit on for-3.8/drivers) > > > > The following changes since commit a13c29ddf73d3be4fbb2b1bbced64014986cd87a: > > Jens Axboe (1): > > Merge branch 'for-jens' of > > git://git.kernel.org/pub/scm/linux/kernel/git/jikos/linux-block > > into for-3.7/drivers> > > are available in the git repository at: > > git://git.drbd.org/linux-drbd.git for-jens > > > > Lars Ellenberg (1): > > drbd: fix regression: potential NULL pointer dereference > > > > drivers/block/drbd/drbd_int.h |5 + > > drivers/block/drbd/drbd_main.c |8 ++-- > > 2 files changed, 11 insertions(+), 2 deletions(-) > > Sure, of course I'll take a regression fix. But the fix does not apply > to current tree: > > axboe@nelson:/src/linux-block $ patch -p1 --dry-run < ~/1.txt > patching file drivers/block/drbd/drbd_int.h > Hunk #1 FAILED at 2545. > 1 out of 1 hunk FAILED -- saving rejects to file > drivers/block/drbd/drbd_int.h.rej patching file > drivers/block/drbd/drbd_main.c > Hunk #1 FAILED at 4232. > 1 out of 1 hunk FAILED -- saving rejects to file > drivers/block/drbd/drbd_main > > Regression fixes for the current tree should be based on the current > tree, looks like you used an outdated for-3.7/drivers branch and this > fix depends on other fixes. Hmm, apparently the changes I submitted to you on October 2 and 3 (which where pulled by you into the for-3.7/drivers tree) never found their way into Linus' tree. (I was not aware of that) The mentioned patch fixes a regression there. Ok, then please ignore this pull request. I will send a new one for for-3.8/drivers in a few days. Best, Phil -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net: move "IPv6: sending pkt_too_big to self" to NETDEBUG
ip6_xmit checks if the outgoing packet is larger than the path MTU and emits ICMPv6 packet too big locally if this is the case. Logging this, even at KERN_DEBUG, confuses users. It is also not actually helpful for debugging, given that there is no reference to the connection that triggered this event. Hence move this message to LIMIT_NETDEBUG, as suggested by Andi Kleen back in 2001 (<20010215231715.26...@colin.muc.de>). Signed-off-by: Philipp Kern --- net/ipv6/ip6_output.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 5b2d63e..707002f 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -241,7 +241,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, dst->dev, dst_output); } - net_dbg_ratelimited("IPv6: sending pkt_too_big to self\n"); + LIMIT_NETDEBUG("IPv6: sending pkt_too_big to self\n"); skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] net: move "IPv6: sending pkt_too_big to self" to NETDEBUG
On Sat, Jul 28, 2012 at 10:29:20AM -0700, Joe Perches wrote: > On Sat, 2012-07-28 at 17:06 +0200, Philipp Kern wrote: > > ip6_xmit checks if the outgoing packet is larger than the path MTU and > > emits ICMPv6 packet too big locally if this is the case. Logging this, > > even at KERN_DEBUG, confuses users. It is also not actually helpful for > > debugging, given that there is no reference to the connection that > > triggered this event. > [] > > diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c > [] > > @@ -241,7 +241,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, > > struct flowi6 *fl6, > >dst->dev, dst_output); > > } > > > > - net_dbg_ratelimited("IPv6: sending pkt_too_big to self\n"); > > + LIMIT_NETDEBUG("IPv6: sending pkt_too_big to self\n"); > LIMIT_NETDEBUG doesn't include a logging level. > Add a KERN_DEBUG prefix or another KERN_. True, sorry, and thanks. That got lost with the change to net_dbg_ratelimited. > Maybe it'd be better to add the context too. Right. What kind of context do you want to see? Would saddr, daddr and dst_mtu be enough? What about skb->len / local_df / skb_is_gso (which are in the condition of the preceding if)? Kind regards Philipp Kern signature.asc Description: Digital signature
Re: [PATCH v5 3/4] misc: sram: Add optional clock
Am Freitag, den 26.10.2012, 12:17 -0400 schrieb Paul Gortmaker: > On Thu, Oct 18, 2012 at 10:27 AM, Philipp Zabel > wrote: > > On some platforms the SRAM needs a clock to be enabled explicitly. > > > > Signed-off-by: Philipp Zabel > > --- > > drivers/misc/sram.c | 10 ++ > > 1 file changed, 10 insertions(+) > > > > diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c > > index 7a363f2..0cc2e75 100644 > > --- a/drivers/misc/sram.c > > +++ b/drivers/misc/sram.c > > @@ -21,6 +21,8 @@ > > #include > > #include > > #include > > +#include > > +#include > > #include > > #include > > #include > > @@ -29,6 +31,7 @@ > > > > struct sram_dev { > > struct gen_pool *pool; > > + struct clk *clk; > > }; > > I see another field gets added to the struct here. (yet another > reason to have it folded into the original) But you still > really don't need to create a sram_dev for this, because... > > > > > static int __devinit sram_probe(struct platform_device *pdev) > > @@ -53,6 +56,10 @@ static int __devinit sram_probe(struct platform_device > > *pdev) > > if (!sram) > > return -ENOMEM; > > > > + sram->clk = devm_clk_get(&pdev->dev, NULL); > > + if (!IS_ERR(sram->clk)) > > + clk_prepare_enable(sram->clk); > > + > > sram->pool = gen_pool_create(PAGE_SHIFT, -1); > > if (!sram->pool) > > return -ENOMEM; > > @@ -80,6 +87,9 @@ static int __devexit sram_remove(struct platform_device > > *pdev) > > > > gen_pool_destroy(sram->pool); > > > > + if (!IS_ERR(sram->clk)) > > + clk_disable_unprepare(sram->clk); > > + > > ...here, this looks confusing with the use of IS_ERR on > an entity that was not recently assigned to. Right. How about I set sram->clk = NULL in sram_probe if devm_clk_get returns an error value? > Instead, just > put a "struct clk *clk;" on the stack and do the > >clk = devm_clk_get(&pdev->dev, NULL); > > in both the init and the teardown. Then the code will be > more readable. Calling devm_clk_get on the same clock twice seems a bit weird. I expect that eventually someone will want to disable clocks during suspend, so I'd prefer to keep the clk pointer around. regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5 3/4] misc: sram: Add optional clock
Am Freitag, den 26.10.2012, 11:18 -0400 schrieb Paul Gortmaker: > On Thu, Oct 18, 2012 at 10:27 AM, Philipp Zabel > wrote: > > On some platforms the SRAM needs a clock to be enabled explicitly. > > Since this is a file that you've just created in the previous commit, > I don't see why this needs to exist as a standalone commit, vs just > being folded back into the previous commit? you are right, I'll do that. thanks Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5 2/4] misc: Generic on-chip SRAM allocation driver
Hi Paul, thank you for your comments. Am Freitag, den 26.10.2012, 12:07 -0400 schrieb Paul Gortmaker: > On Thu, Oct 18, 2012 at 10:27 AM, Philipp Zabel > wrote: > > This driver requests and remaps a memory region as configured in the > > device tree. It serves memory from this region via the genalloc API. > > > > Other drivers can retrieve the genalloc pool from a phandle pointing > > to this drivers' device node in the device tree. > > > > Signed-off-by: Philipp Zabel > > Reviewed-by: Shawn Guo > > --- > > Documentation/devicetree/bindings/misc/sram.txt | 17 > > drivers/misc/Kconfig|9 ++ > > drivers/misc/Makefile |1 + > > drivers/misc/sram.c | 111 > > +++ > > 4 files changed, 138 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/misc/sram.txt > > create mode 100644 drivers/misc/sram.c > > > > diff --git a/Documentation/devicetree/bindings/misc/sram.txt > > b/Documentation/devicetree/bindings/misc/sram.txt > > new file mode 100644 > > index 000..b64136c > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/misc/sram.txt > > @@ -0,0 +1,17 @@ > > +Generic on-chip SRAM > > + > > +Simple IO memory regions to be managed by the genalloc API. > > + > > +Required properties: > > + > > +- compatible : sram > > + > > +- reg : SRAM iomem address range > > + > > +Example: > > + > > +sram: sram@5c00 { > > + compatible = "sram"; > > + reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ > > +}; > > + > > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig > > index b151b7c..c5bbd00 100644 > > --- a/drivers/misc/Kconfig > > +++ b/drivers/misc/Kconfig > > @@ -499,6 +499,15 @@ config USB_SWITCH_FSA9480 > > stereo and mono audio, video, microphone and UART data to use > > a common connector port. > > > > +config SRAM > > + bool "Generic on-chip SRAM driver" > > If it is bool, then why bother with module.h and all the > MODULE_AUTHOR and similar stuff? Yes. This driver was a module before I noticed that I then would have to keep track in genalloc to avoid module unloading while some SRAM is allocated. It seemed a bit too invasive. > > + depends on HAS_IOMEM > > + select GENERIC_ALLOCATOR > > + help > > + This driver allows to declare a memory region to be managed > > + by the genalloc API. It is supposed to be used for small > > + on-chip SRAM areas found on many ARM SoCs. > > Probably no need to call out ARM specifically here. I'm pretty sure > quite a few of the powerpc parts have SRAM too. Sure, I'll just s/ARM // then. > > + > > source "drivers/misc/c2port/Kconfig" > > source "drivers/misc/eeprom/Kconfig" > > source "drivers/misc/cb710/Kconfig" > > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile > > index 2129377..d845690 100644 > > --- a/drivers/misc/Makefile > > +++ b/drivers/misc/Makefile > > @@ -49,3 +49,4 @@ obj-y += carma/ > > obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o > > obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ > > obj-$(CONFIG_INTEL_MEI)+= mei/ > > +obj-$(CONFIG_SRAM) += sram.o > > diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c > > new file mode 100644 > > index 000..7a363f2 > > --- /dev/null > > +++ b/drivers/misc/sram.c > > @@ -0,0 +1,111 @@ > > +/* > > + * Generic on-chip SRAM allocation driver > > + * > > + * Copyright (C) 2012 Philipp Zabel, Pengutronix > > + * > > + * 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. > > + * > > + * You should have received a copy of the GNU General Public License > > + * along with this program; if not, write to the Free Software > > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Bos
[GIT PULL] 4 fixes for drbd
Hi Jens, please consider to pull these fixes in. It is based on your for-3.7/drivers branch. Best regards, Phil The following changes since commit 34a73dd594699dc3834167297a74c43948bb6e41: Revert "memstick: add support for legacy memorysticks" (2012-10-10 16:13:26 -0600) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens for you to fetch changes up to 731d4596a6f3ba41418a0b11018c453456c51d92: drbd: check return of kmalloc in receive_uuids (2012-10-29 13:18:13 +0100) Jing Wang (1): drbd: check return of kmalloc in receive_uuids Lars Ellenberg (2): drbd: fix regression: potential NULL pointer dereference drbd: don't try to clear bits once the disk has failed Philipp Reisner (1): drbd: Broadcast sync progress no more often than once per second drivers/block/drbd/drbd_actlog.c | 19 +-- drivers/block/drbd/drbd_int.h |6 ++ drivers/block/drbd/drbd_main.c |8 ++-- drivers/block/drbd/drbd_nl.c |5 + drivers/block/drbd/drbd_receiver.c |4 drivers/block/drbd/drbd_worker.c |4 6 files changed, 38 insertions(+), 8 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC 0/6] ARM: OMAP2+: AM43x/AM335x prcm reset driver
| 157 > + > drivers/reset/core.c | 32 + > include/linux/reset-controller.h | 2 + > include/linux/reset.h | 2 + > 10 files changed, 235 insertions(+) > create mode 100644 Documentation/devicetree/bindings/arm/omap/prcm.txt > create mode 100644 drivers/reset/amx3_reset.c regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC 0/6] ARM: OMAP2+: AM43x/AM335x prcm reset driver
Am Donnerstag, den 05.09.2013, 21:26 +0530 schrieb Afzal Mohammed: > Hi Philipp, > > On Thursday 05 September 2013 03:37 PM, Philipp Zabel wrote: > > Am Montag, den 02.09.2013, 19:41 +0530 schrieb Afzal Mohammed: > > >> Two new reset API's are provided to check whether reset is ready and > >> to clear reset. This would be required in case IP needs to mix reset > >> handling procedure with power/clock managment procedure to achieve > >> proper reset and these procedures are sometimes IP specific that would > >> make it difficult to handle reset fully in pm_runtime platform support. > > >> client IP handling s/w (DT based) should do as follows: > > >> 2. In driver, that require reset to be deasserted, > >> (this is the sequence required for gfx on AM43x/AM335x, this would > >> depend on requirements of the IP) > >> > >>mydriver_probe(struct platform device *pdev) > >>{ > >>: > >>: > >>reset_control_get(&pdev->dev, NULL); > >>reset_control_clear_reset(); > >>reset_control_deassert(); > >>pm_runtime_get_sync(); > >>if (reset_control_is_reset() != true) > >>goto err; > >>reset_control_put(); > >>: > >>: > >>} > > > if possible, I'd like to move this logic into the reset controller > > driver. Can this be reordered to enable power before deasserting the > > reset line (assuming it is initially asserted)? In this case, I'd > > suggest to just call device_reset: > > > > pm_runtime_get_sync(&pdev->dev); > > ret = device_reset(&pdev->dev); > > if (ret) > > goto err; > > > > The ops.reset callback in the prcm driver then can handle clearing > > the reset status bit, deasserting the reset control bit, and waiting for > > the reset status bit to be set (or timing out with an error). > > I too would have loved to have it in such a clean way and was initially > proceeding in that direction, but there is an issue specific to OMAP > family SoC's, which was required to be taken care of (even though > present use case for AM335x/AM43x would work [as it does not have > hardware supervised clockdomain mode] with a small change in platform > level power management support code - a generic one shared with other > OMAP family SoC's) > > For a module to be reset, clock domain to which the module clock belongs > should be set to software supervised mode. During "pm_runtime_get_sync", > in OMAP platform level handling code, it first put clockdomain into > software supervised mode, enables clock to module, and once module is > ready, module will be put to hardware supervised mode. In hardware > supervised mode, reset may not happen. > > So if device_reset() is done after pm_runtime_get_sync(), reset may not > happen as by the time device_reset() is called, clockdomain would be in > hardware supervised mode. But in other case, as reset is already > deasserted when pm_runtime_get_sync() is called, module would be reset > as it first puts to software supervised mode. > > And device reset would happen only upon enabling clock to module (if > reset was deasserted) by pm_runtime_get_sync(), so reset status has to > be checked after pm call, preventing us having device_reset() before > pm_runtime_get_sync(), or else in that case we have to sacrifice on > reset status checking (which may not be reliable) > > Another alternative would have been to integrate this reset handling in > low level power management code thus hiding all reset handling from > driver, but as far as I know the reset sequence to be done is sometimes > IP specific, preventing it. So if I understand correctly, the only problem is that on OMAP the clock needs to be enabled to deassert the reset, but as long as the clock domain is in hardware supervised mode, it won't be enabled? Would it be possible to create an internal API to switch the clock domain to software supervised mode, which can be used both by the code behind pm_runtime_get_sync and reset_control_deassert? regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] reset: Add non CONFIG_RESET_CONTROLLER routines
Hi Ivan, Am Donnerstag, den 10.10.2013, 12:14 +0300 schrieb Ivan T. Ivanov: > From: "Ivan T. Ivanov" > > Make sure client drivers will still build on systems > without reset control support. the stubs should at least return errors, but then this turns a compile time error into a runtime error for devices that don't work without being properly reset. Please also refer to this thread: http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/174758.html regards Philipp > Signed-off-by: Ivan T. Ivanov > Cc: Pavel Machek > Cc: Stephen Warren > Cc: Shawn Guo > Cc: Marek Vasut > --- > include/linux/reset.h | 44 > 1 file changed, 44 insertions(+) > > diff --git a/include/linux/reset.h b/include/linux/reset.h > index 6082247..0df3e30 100644 > --- a/include/linux/reset.h > +++ b/include/linux/reset.h > @@ -4,6 +4,8 @@ > struct device; > struct reset_control; > > +#if defined(CONFIG_RESET_CONTROLLER) > + > int reset_control_reset(struct reset_control *rstc); > int reset_control_assert(struct reset_control *rstc); > int reset_control_deassert(struct reset_control *rstc); > @@ -14,4 +16,46 @@ struct reset_control *devm_reset_control_get(struct device > *dev, const char *id) > > int device_reset(struct device *dev); > > +#else /* !CONFIG_RESET_CONTROLLER */ > + > +/* > + * Make sure client drivers will still build on systems without > + * reset control support. > + */ > +static inline int reset_control_reset(struct reset_control *rstc) > +{ > + return 0; > +} > + > +static inline int reset_control_assert(struct reset_control *rstc) > +{ > + return 0; > +} > + > +static inline int reset_control_deassert(struct reset_control *rstc) > +{ > + return 0; > +} > + > +static inline struct reset_control * > +reset_control_get(struct device *dev, const char *id) > +{ > + return 0; > +} > + > +static inline void reset_control_put(struct reset_control *rstc){} > + > +static inline struct reset_control * > +devm_reset_control_get(struct device *dev, const char *id) > +{ > + return NULL; > +} > + > +static inline int device_reset(struct device *dev) > +{ > + return 0; > +} > + > +#endif > + > #endif -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Drbd-dev] [PATCH] drbd: use list_move_tail instead of list_del/list_add_tail
Thanks, applied. Best regards, Phil > From: Wei Yongjun > > Using list_move_tail() instead of list_del() + list_add_tail(). > > spatch with a semantic match is used to found this problem. > (http://coccinelle.lip6.fr/) > > Signed-off-by: Wei Yongjun > --- > drivers/block/drbd/drbd_worker.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/block/drbd/drbd_worker.c > b/drivers/block/drbd/drbd_worker.c index 6bce2cc..a196281 100644 > --- a/drivers/block/drbd/drbd_worker.c > +++ b/drivers/block/drbd/drbd_worker.c > @@ -141,8 +141,7 @@ static void drbd_endio_write_sec_final(struct > drbd_epoch_entry *e) __releases(lo > > spin_lock_irqsave(&mdev->req_lock, flags); > mdev->writ_cnt += e->size >> 9; > - list_del(&e->w.list); /* has been on active_ee or sync_ee */ > - list_add_tail(&e->w.list, &mdev->done_ee); > + list_move_tail(&e->w.list, &mdev->done_ee); > > /* No hlist_del_init(&e->collision) here, we did not send the Ack yet, >* neither did we wake possibly waiting conflicting requests. > > > ___ > drbd-dev mailing list > drbd-...@lists.linbit.com > http://lists.linbit.com/mailman/listinfo/drbd-dev -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 0/6] Add device tree support for on-chip SRAM
These patches add support to configure on-chip SRAM via device-tree node and to obtain the resulting genalloc pool from a phandle pointing at the node. This allows drivers to allocate SRAM with the genalloc API without hard-coding the genalloc pool address. The on-chip SRAM on i.MX53 and i.MX6q is registered via device tree and changed to use the simple generic SRAM driver: ocram: ocram@0090 { compatible = "fsl,imx-ocram", "sram"; reg = <0x0090 0x3f000>; }; A driver that needs to allocate SRAM buffers, like the video processing unit on i.MX53, can retrieve the genalloc pool from a phandle in the device tree using of_get_named_gen_pool(node, "iram", 0) from patch 1: vpu@63ff4000 { /* ... */ iram = <&ocram>; }; Changes since v3: - Added devicetree binding documentation - Register platform driver early with postcore_initcall - Added optional SRAM clock support. regards Philipp --- Documentation/devicetree/bindings/misc/sram.txt | 17 arch/arm/boot/dts/imx53.dtsi|5 + arch/arm/boot/dts/imx6q.dtsi|5 + arch/arm/mach-imx/clk-imx6q.c |1 + arch/arm/plat-mxc/Kconfig |4 - arch/arm/plat-mxc/Makefile |1 - arch/arm/plat-mxc/include/mach/iram.h | 41 arch/arm/plat-mxc/iram_alloc.c | 73 -- drivers/misc/Kconfig|9 ++ drivers/misc/Makefile |1 + drivers/misc/sram.c | 121 +++ include/linux/genalloc.h| 14 +++ lib/genalloc.c | 67 + 13 files changed, 240 insertions(+), 119 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 1/6] genalloc: add a global pool list, allow to find pools by phys address
This patch keeps all created pools in a global list and adds two functions that allow to retrieve the gen_pool pointer from a known physical address and from a device tree node. Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo --- include/linux/genalloc.h | 14 ++ lib/genalloc.c | 67 ++ 2 files changed, 81 insertions(+) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 5e98eeb..d498c43 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -33,6 +33,7 @@ * General purpose special memory pool descriptor. */ struct gen_pool { + struct list_head next_pool; /* pool in global list */ spinlock_t lock; struct list_head chunks;/* list of chunks in this pool */ int min_alloc_order;/* minimum allocation order */ @@ -78,4 +79,17 @@ extern void gen_pool_for_each_chunk(struct gen_pool *, void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); extern size_t gen_pool_avail(struct gen_pool *); extern size_t gen_pool_size(struct gen_pool *); +extern struct gen_pool *gen_pool_find_by_phys(phys_addr_t phys); + +struct device_node; +#ifdef CONFIG_OF +extern struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index); +#else +inline struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + return NULL; +} +#endif #endif /* __GENALLOC_H__ */ diff --git a/lib/genalloc.c b/lib/genalloc.c index 6bc04aa..90699ac 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -34,6 +34,11 @@ #include #include #include +#include +#include + +static LIST_HEAD(pools); +static DEFINE_SPINLOCK(list_lock); static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) { @@ -152,6 +157,9 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid) spin_lock_init(&pool->lock); INIT_LIST_HEAD(&pool->chunks); pool->min_alloc_order = min_alloc_order; + spin_lock(&list_lock); + list_add_rcu(&pool->next_pool, &pools); + spin_unlock(&list_lock); } return pool; } @@ -234,6 +242,9 @@ void gen_pool_destroy(struct gen_pool *pool) int order = pool->min_alloc_order; int bit, end_bit; + spin_lock(&list_lock); + list_del_rcu(&pool->next_pool); + spin_unlock(&list_lock); list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); list_del(&chunk->next_chunk); @@ -400,3 +411,59 @@ size_t gen_pool_size(struct gen_pool *pool) return size; } EXPORT_SYMBOL_GPL(gen_pool_size); + +/** + * gen_pool_find_by_phys - find a pool by physical start address + * @phys: physical address as added with gen_pool_add_virt + * + * Returns the pool that contains the chunk starting at phys, + * or NULL if not found. + */ +struct gen_pool *gen_pool_find_by_phys(phys_addr_t phys) +{ + struct gen_pool *pool, *found = NULL; + struct gen_pool_chunk *chunk; + + rcu_read_lock(); + list_for_each_entry_rcu(pool, &pools, next_pool) { + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { + if (phys == chunk->phys_addr) { + found = pool; + break; + } + } + } + rcu_read_unlock(); + + return found; +} +EXPORT_SYMBOL_GPL(gen_pool_find_by_phys); + +#ifdef CONFIG_OF +/** + * of_get_named_gen_pool - find a pool by phandle property + * @np: device node + * @propname: property name containing phandle(s) + * @index: index into the phandle array + * + * Returns the pool that contains the chunk starting at the physical + * address of the device tree node pointed at by the phandle property, + * or NULL if not found. + */ +struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + struct device_node *np_pool; + struct resource res; + int ret; + + np_pool = of_parse_phandle(np, propname, index); + if (!np_pool) + return NULL; + ret = of_address_to_resource(np_pool, 0, &res); + if (ret < 0) + return NULL; + return gen_pool_find_by_phys((phys_addr_t) res.start); +} +EXPORT_SYMBOL_GPL(of_get_named_gen_pool); +#endif /* CONFIG_OF */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 4/6] ARM i.MX: remove IRAM_ALLOC facility
A generic on-chip SRAM allocator driver can be used instead. Users of the iram_alloc/free API should convert to the genalloc API: - virt = iram_alloc(SIZE, &phys); + gen_pool_alloc(iram_pool, SIZE); + phys = gen_pool_virt_to_phys(iram_pool, virt); /* ... */ - iram_free(virt, SIZE); + gen_pool_free(iram_pool, virt, SIZE); Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo --- arch/arm/plat-mxc/Kconfig |4 -- arch/arm/plat-mxc/Makefile|1 - arch/arm/plat-mxc/include/mach/iram.h | 41 -- arch/arm/plat-mxc/iram_alloc.c| 73 - 4 files changed, 119 deletions(-) delete mode 100644 arch/arm/plat-mxc/include/mach/iram.h delete mode 100644 arch/arm/plat-mxc/iram_alloc.c diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index baf9064..8e63f10 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -82,8 +82,4 @@ config IMX_HAVE_IOMUX_V1 config ARCH_MXC_IOMUX_V3 bool -config IRAM_ALLOC - bool - select GENERIC_ALLOCATOR - endif diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 6ac7200..bdf370f 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_MXC_AVIC) += avic.o obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o -obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o obj-$(CONFIG_MXC_ULPI) += ulpi.o obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o diff --git a/arch/arm/plat-mxc/include/mach/iram.h b/arch/arm/plat-mxc/include/mach/iram.h deleted file mode 100644 index 022690c..000 --- a/arch/arm/plat-mxc/include/mach/iram.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -#include - -#ifdef CONFIG_IRAM_ALLOC - -int __init iram_init(unsigned long base, unsigned long size); -void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr); -void iram_free(unsigned long dma_addr, unsigned int size); - -#else - -static inline int __init iram_init(unsigned long base, unsigned long size) -{ - return -ENOMEM; -} - -static inline void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) -{ - return NULL; -} - -static inline void iram_free(unsigned long base, unsigned long size) {} - -#endif diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/plat-mxc/iram_alloc.c deleted file mode 100644 index 074c386..000 --- a/arch/arm/plat-mxc/iram_alloc.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -static unsigned long iram_phys_base; -static void __iomem *iram_virt_base; -static struct gen_pool *iram_pool; - -static inline void __iomem *iram_phys_to_virt(unsigned long p) -{ - return iram_virt_base + (p - iram_phys_base); -} - -void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) -{ - if (!iram_pool) - return NULL; - - *dma_addr = gen_pool_alloc(iram_pool, size); - pr_debug("iram alloc - %dB@0x%lX\n", size, *dma_addr); - if (!*dma_addr) - return NULL; - return iram_phys_to_virt(*dma_addr); -} -EXPORT_SYMBOL(iram_alloc); - -void iram_free(unsigned long addr, unsigned int size) -{ - if (!iram_pool) -
[PATCH v4 6/6] ARM i.MX6q: Add ocram clkdev entry
Signed-off-by: Philipp Zabel --- arch/arm/mach-imx/clk-imx6q.c |1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 4233d9e..5912966 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -439,6 +439,7 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); clk_register_clkdev(clk[ahb], "ahb", NULL); clk_register_clkdev(clk[cko1], "cko1", NULL); + clk_register_clkdev(clk[ocram], NULL, "90.ocram"); for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) clk_prepare_enable(clk[clks_init_on[i]]); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 5/6] misc: sram: Add optional clock
On some platforms the SRAM needs a clock to be enabled explicitly. Signed-off-by: Philipp Zabel --- drivers/misc/sram.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 7a363f2..0cc2e75 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -29,6 +31,7 @@ struct sram_dev { struct gen_pool *pool; + struct clk *clk; }; static int __devinit sram_probe(struct platform_device *pdev) @@ -53,6 +56,10 @@ static int __devinit sram_probe(struct platform_device *pdev) if (!sram) return -ENOMEM; + sram->clk = devm_clk_get(&pdev->dev, NULL); + if (!IS_ERR(sram->clk)) + clk_prepare_enable(sram->clk); + sram->pool = gen_pool_create(PAGE_SHIFT, -1); if (!sram->pool) return -ENOMEM; @@ -80,6 +87,9 @@ static int __devexit sram_remove(struct platform_device *pdev) gen_pool_destroy(sram->pool); + if (!IS_ERR(sram->clk)) + clk_disable_unprepare(sram->clk); + return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 3/6] ARM: dts: add sram for imx53 and imx6q
Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo --- arch/arm/boot/dts/imx53.dtsi |5 + arch/arm/boot/dts/imx6q.dtsi |5 + 2 files changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index cd37165..2767a92 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -337,5 +337,10 @@ status = "disabled"; }; }; + + ocram: ocram@f800 { + compatible = "fsl,imx-ocram", "sram"; + reg = <0xf800 0x2>; + }; }; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index fd57079..1e463c4 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -111,6 +111,11 @@ status = "disabled"; }; + ocram: ocram@0090 { + compatible = "fsl,imx-ocram", "sram"; + reg = <0x0090 0x3f000>; + }; + timer@00a00600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x00a00600 0x20>; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 2/6] misc: Generic on-chip SRAM allocation driver
This driver requests and remaps a memory region as configured in the device tree. It serves memory from this region via the genalloc API. Other drivers can retrieve the genalloc pool from a phandle pointing to this drivers' device node in the device tree. Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo --- Changes since v3: - Added devicetree binding documentation - Register platform driver with postcore_initcall --- Documentation/devicetree/bindings/misc/sram.txt | 17 drivers/misc/Kconfig|9 ++ drivers/misc/Makefile |1 + drivers/misc/sram.c | 111 +++ 4 files changed, 138 insertions(+) create mode 100644 Documentation/devicetree/bindings/misc/sram.txt create mode 100644 drivers/misc/sram.c diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt new file mode 100644 index 000..8bb26fc --- /dev/null +++ b/Documentation/devicetree/bindings/misc/sram.txt @@ -0,0 +1,17 @@ +Generic on-chip SRAM + +Simple IO memory regions to be managed by the genalloc API. + +Required properties: + +- compatible : sram + +- reg : SRAM iomem address range + +Example: + +sram: sram@5c00 { + compatible = "sram"; + reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ +}; + diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 98a442d..9a3395f 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -509,6 +509,15 @@ config USB_SWITCH_FSA9480 stereo and mono audio, video, microphone and UART data to use a common connector port. +config SRAM + bool "Generic on-chip SRAM driver" + depends on HAS_IOMEM + select GENERIC_ALLOCATOR + help + This driver allows to declare a memory region to be managed + by the genalloc API. It is supposed to be used for small + on-chip SRAM areas found on many ARM SoCs. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b88df7a..ccc759a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -50,3 +50,4 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_INTEL_MEI)+= mei/ +obj-$(CONFIG_SRAM) += sram.o diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c new file mode 100644 index 000..7a363f2 --- /dev/null +++ b/drivers/misc/sram.c @@ -0,0 +1,111 @@ +/* + * Generic on-chip SRAM allocation driver + * + * Copyright (C) 2012 Philipp Zabel, Pengutronix + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct sram_dev { + struct gen_pool *pool; +}; + +static int __devinit sram_probe(struct platform_device *pdev) +{ + void __iomem *virt_base; + struct sram_dev *sram; + struct resource *res; + unsigned long size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + size = resource_size(res); + + virt_base = devm_request_and_ioremap(&pdev->dev, res); + if (!virt_base) + return -EADDRNOTAVAIL; + + sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL); + if (!sram) + return -ENOMEM; + + sram->pool = gen_pool_create(PAGE_SHIFT, -1); + if (!sram->pool) + return -ENOMEM; + + ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base, + res->start, size, -1); + if (ret < 0) { + gen_pool_destroy(sram->pool); + return ret; + } + + platform_set_drvdata(pdev, sram); + + dev_dbg(&pdev->dev, "SRAM pool: %ld KiB @ 0x%p\n", size / 1024, virt_base); + + return 0; +} + +static int __devexit sram_remove(struct platform_device *pdev) +{ + struct sram_dev *sram = platform_get_drvdata(p
Re: [PATCH v7 0/4] Add generic driver for on-chip SRAM
Hi, On Fri, 2012-11-23 at 15:24 +0100, Philipp Zabel wrote: > These patches add support to configure on-chip SRAM via device-tree > node or platform data and to obtain the resulting genalloc pool from > the physical address or a phandle pointing at the device tree node. > This allows drivers to allocate SRAM with the genalloc API without > hard-coding the genalloc pool pointer. are there any further comments on this series? > The on-chip SRAM on i.MX53 and i.MX6q can be registered via device tree > and changed to use the simple generic SRAM driver: > > ocram: ocram@0090 { > compatible = "fsl,imx-ocram", "sram"; > reg = <0x0090 0x3f000>; > }; > > A driver that needs to allocate SRAM buffers, like the video processing > unit on i.MX53, can retrieve the genalloc pool from a phandle in the > device tree using of_get_named_gen_pool(node, "iram", 0) from patch 1: > > vpu@63ff4000 { > /* ... */ > iram = <&ocram>; > }; > > The allocation granularity is hard-coded to 32 bytes for now, > until a way to configure it can be agreed upon. There is overhead > for bigger SRAMs, where only a much coarser allocation granularity > is needed: At 32 bytes minimum allocation size, a 256 KiB SRAM > needs a 1 KiB bitmap to track allocations. > > Once everybody is ok with it, could the first two patches be merged > through the char-misc tree? I'll resend the i.MX and coda patches to > the respective lists afterwards. Arnd, Greg, would you take the first patch "genalloc: add a global pool list, allow to find pools by phys address" into the char-misc tree if there are no vetoes? Or should I try and get it merged separately, first? regards Philipp > Changes since v6: > - Reduced the hard coded allocation granularity to 32 bytes. > > regards > Philipp > > --- > Documentation/devicetree/bindings/misc/sram.txt | 17 > arch/arm/boot/dts/imx53.dtsi|5 + > arch/arm/boot/dts/imx6q.dtsi|6 ++ > drivers/media/platform/Kconfig |3 +- > drivers/media/platform/coda.c | 47 ++--- > drivers/misc/Kconfig|9 ++ > drivers/misc/Makefile |1 + > drivers/misc/sram.c | 121 > +++ > include/linux/genalloc.h| 14 +++ > lib/genalloc.c | 67 + > 10 files changed, 274 insertions(+), 16 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v7 0/4] Add generic driver for on-chip SRAM
On Tue, 2012-12-04 at 08:19 -0800, Greg Kroah-Hartman wrote: > On Tue, Dec 04, 2012 at 09:53:38AM +0100, Philipp Zabel wrote: > > Hi, > > > > On Fri, 2012-11-23 at 15:24 +0100, Philipp Zabel wrote: > > > These patches add support to configure on-chip SRAM via device-tree > > > node or platform data and to obtain the resulting genalloc pool from > > > the physical address or a phandle pointing at the device tree node. > > > This allows drivers to allocate SRAM with the genalloc API without > > > hard-coding the genalloc pool pointer. > > > > are there any further comments on this series? > > > > > The on-chip SRAM on i.MX53 and i.MX6q can be registered via device tree > > > and changed to use the simple generic SRAM driver: > > > > > > ocram: ocram@0090 { > > > compatible = "fsl,imx-ocram", "sram"; > > > reg = <0x0090 0x3f000>; > > > }; > > > > > > A driver that needs to allocate SRAM buffers, like the video processing > > > unit on i.MX53, can retrieve the genalloc pool from a phandle in the > > > device tree using of_get_named_gen_pool(node, "iram", 0) from patch 1: > > > > > > vpu@63ff4000 { > > > /* ... */ > > > iram = <&ocram>; > > > }; > > > > > > The allocation granularity is hard-coded to 32 bytes for now, > > > until a way to configure it can be agreed upon. There is overhead > > > for bigger SRAMs, where only a much coarser allocation granularity > > > is needed: At 32 bytes minimum allocation size, a 256 KiB SRAM > > > needs a 1 KiB bitmap to track allocations. > > > > > > Once everybody is ok with it, could the first two patches be merged > > > through the char-misc tree? I'll resend the i.MX and coda patches to > > > the respective lists afterwards. > > > > Arnd, Greg, would you take the first patch "genalloc: add a global pool > > list, allow to find pools by phys address" into the char-misc tree if > > there are no vetoes? Or should I try and get it merged separately, > > first? > > It's too late for anything new for 3.8, so how about resending this all > after 3.8-rc1 is out and we can take it from there? Ok, I'll do that. thanks Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] regmap: default Y if REGMAP_MMIO is selected
The syscon mfd driver selects REGMAP_MMIO and uses struct regmap_config, which is only defined if CONFIG_REGMAP is enabled. Signed-off-by: Philipp Zabel --- drivers/base/regmap/Kconfig |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig index 6be390b..89887f9 100644 --- a/drivers/base/regmap/Kconfig +++ b/drivers/base/regmap/Kconfig @@ -3,7 +3,7 @@ # subsystems should select the appropriate symbols. config REGMAP - default y if (REGMAP_I2C || REGMAP_SPI) + default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_MMIO) select LZO_COMPRESS select LZO_DECOMPRESS select IRQ_DOMAIN if REGMAP_IRQ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] regmap: default Y if REGMAP_MMIO is selected
Am Mittwoch, den 17.10.2012, 21:32 +0900 schrieb Mark Brown: > On Wed, Oct 17, 2012 at 02:31:16PM +0200, Philipp Zabel wrote: > > The syscon mfd driver selects REGMAP_MMIO and uses struct regmap_config, > > which is only defined if CONFIG_REGMAP is enabled. > > Already fixed by someone else, can't remember who now. Will send to > Linus soon. Great, thanks. regrads Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 3/4] misc: sram: Add optional clock
On some platforms the SRAM needs a clock to be enabled explicitly. Signed-off-by: Philipp Zabel --- drivers/misc/sram.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 7a363f2..0cc2e75 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -29,6 +31,7 @@ struct sram_dev { struct gen_pool *pool; + struct clk *clk; }; static int __devinit sram_probe(struct platform_device *pdev) @@ -53,6 +56,10 @@ static int __devinit sram_probe(struct platform_device *pdev) if (!sram) return -ENOMEM; + sram->clk = devm_clk_get(&pdev->dev, NULL); + if (!IS_ERR(sram->clk)) + clk_prepare_enable(sram->clk); + sram->pool = gen_pool_create(PAGE_SHIFT, -1); if (!sram->pool) return -ENOMEM; @@ -80,6 +87,9 @@ static int __devexit sram_remove(struct platform_device *pdev) gen_pool_destroy(sram->pool); + if (!IS_ERR(sram->clk)) + clk_disable_unprepare(sram->clk); + return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 1/4] genalloc: add a global pool list, allow to find pools by phys address
This patch keeps all created pools in a global list and adds two functions that allow to retrieve the gen_pool pointer from a known physical address and from a device tree node. Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo --- include/linux/genalloc.h | 14 ++ lib/genalloc.c | 67 ++ 2 files changed, 81 insertions(+) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index dd7c569..91d606e 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -47,6 +47,7 @@ typedef unsigned long (*genpool_algo_t)(unsigned long *map, * General purpose special memory pool descriptor. */ struct gen_pool { + struct list_head next_pool; /* pool in global list */ spinlock_t lock; struct list_head chunks;/* list of chunks in this pool */ int min_alloc_order;/* minimum allocation order */ @@ -105,4 +106,17 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data); +extern struct gen_pool *gen_pool_find_by_phys(phys_addr_t phys); + +struct device_node; +#ifdef CONFIG_OF +extern struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index); +#else +inline struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + return NULL; +} +#endif #endif /* __GENALLOC_H__ */ diff --git a/lib/genalloc.c b/lib/genalloc.c index ca208a9..d77d240 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -34,6 +34,11 @@ #include #include #include +#include +#include + +static LIST_HEAD(pools); +static DEFINE_SPINLOCK(list_lock); static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) { @@ -154,6 +159,9 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid) pool->min_alloc_order = min_alloc_order; pool->algo = gen_pool_first_fit; pool->data = NULL; + spin_lock(&list_lock); + list_add_rcu(&pool->next_pool, &pools); + spin_unlock(&list_lock); } return pool; } @@ -236,6 +244,9 @@ void gen_pool_destroy(struct gen_pool *pool) int order = pool->min_alloc_order; int bit, end_bit; + spin_lock(&list_lock); + list_del_rcu(&pool->next_pool); + spin_unlock(&list_lock); list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); list_del(&chunk->next_chunk); @@ -480,3 +491,59 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, return start_bit; } EXPORT_SYMBOL(gen_pool_best_fit); + +/* + * gen_pool_find_by_phys - find a pool by physical start address + * @phys: physical address as added with gen_pool_add_virt + * + * Returns the pool that contains the chunk starting at phys, + * or NULL if not found. + */ +struct gen_pool *gen_pool_find_by_phys(phys_addr_t phys) +{ + struct gen_pool *pool, *found = NULL; + struct gen_pool_chunk *chunk; + + rcu_read_lock(); + list_for_each_entry_rcu(pool, &pools, next_pool) { + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { + if (phys == chunk->phys_addr) { + found = pool; + break; + } + } + } + rcu_read_unlock(); + + return found; +} +EXPORT_SYMBOL_GPL(gen_pool_find_by_phys); + +#ifdef CONFIG_OF +/** + * of_get_named_gen_pool - find a pool by phandle property + * @np: device node + * @propname: property name containing phandle(s) + * @index: index into the phandle array + * + * Returns the pool that contains the chunk starting at the physical + * address of the device tree node pointed at by the phandle property, + * or NULL if not found. + */ +struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + struct device_node *np_pool; + struct resource res; + int ret; + + np_pool = of_parse_phandle(np, propname, index); + if (!np_pool) + return NULL; + ret = of_address_to_resource(np_pool, 0, &res); + if (ret < 0) + return NULL; + return gen_pool_find_by_phys((phys_addr_t) res.start); +} +EXPORT_SYMBOL_GPL(of_get_named_gen_pool); +#endif /* CONFIG_OF */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 2/4] misc: Generic on-chip SRAM allocation driver
This driver requests and remaps a memory region as configured in the device tree. It serves memory from this region via the genalloc API. Other drivers can retrieve the genalloc pool from a phandle pointing to this drivers' device node in the device tree. Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo --- Documentation/devicetree/bindings/misc/sram.txt | 17 drivers/misc/Kconfig|9 ++ drivers/misc/Makefile |1 + drivers/misc/sram.c | 111 +++ 4 files changed, 138 insertions(+) create mode 100644 Documentation/devicetree/bindings/misc/sram.txt create mode 100644 drivers/misc/sram.c diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt new file mode 100644 index 000..b64136c --- /dev/null +++ b/Documentation/devicetree/bindings/misc/sram.txt @@ -0,0 +1,17 @@ +Generic on-chip SRAM + +Simple IO memory regions to be managed by the genalloc API. + +Required properties: + +- compatible : sram + +- reg : SRAM iomem address range + +Example: + +sram: sram@5c00 { + compatible = "sram"; + reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ +}; + diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b151b7c..c5bbd00 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -499,6 +499,15 @@ config USB_SWITCH_FSA9480 stereo and mono audio, video, microphone and UART data to use a common connector port. +config SRAM + bool "Generic on-chip SRAM driver" + depends on HAS_IOMEM + select GENERIC_ALLOCATOR + help + This driver allows to declare a memory region to be managed + by the genalloc API. It is supposed to be used for small + on-chip SRAM areas found on many ARM SoCs. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 2129377..d845690 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -49,3 +49,4 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_INTEL_MEI)+= mei/ +obj-$(CONFIG_SRAM) += sram.o diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c new file mode 100644 index 000..7a363f2 --- /dev/null +++ b/drivers/misc/sram.c @@ -0,0 +1,111 @@ +/* + * Generic on-chip SRAM allocation driver + * + * Copyright (C) 2012 Philipp Zabel, Pengutronix + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct sram_dev { + struct gen_pool *pool; +}; + +static int __devinit sram_probe(struct platform_device *pdev) +{ + void __iomem *virt_base; + struct sram_dev *sram; + struct resource *res; + unsigned long size; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + size = resource_size(res); + + virt_base = devm_request_and_ioremap(&pdev->dev, res); + if (!virt_base) + return -EADDRNOTAVAIL; + + sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL); + if (!sram) + return -ENOMEM; + + sram->pool = gen_pool_create(PAGE_SHIFT, -1); + if (!sram->pool) + return -ENOMEM; + + ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base, + res->start, size, -1); + if (ret < 0) { + gen_pool_destroy(sram->pool); + return ret; + } + + platform_set_drvdata(pdev, sram); + + dev_dbg(&pdev->dev, "SRAM pool: %ld KiB @ 0x%p\n", size / 1024, virt_base); + + return 0; +} + +static int __devexit sram_remove(struct platform_device *pdev) +{ + struct sram_dev *sram = platform_get_drvdata(pdev); + + if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool)) + dev_dbg(
[PATCH v5 0/4] Add generic driver for on-chip SRAM
These patches add support to configure on-chip SRAM via device-tree node or platform data and to obtain the resulting genalloc pool from the physical address or a phandle pointing at the device tree node. This allows drivers to allocate SRAM with the genalloc API without hard-coding the genalloc pool pointer. The on-chip SRAM on i.MX53 and i.MX6q can be registered via device tree and changed to use the simple generic SRAM driver: ocram: ocram@0090 { compatible = "fsl,imx-ocram", "sram"; reg = <0x0090 0x3f000>; alloc-order = <12>; }; A driver that needs to allocate SRAM buffers, like the video processing unit on i.MX53, can retrieve the genalloc pool from a phandle in the device tree using of_get_named_gen_pool(node, "iram", 0) from patch 1: vpu@63ff4000 { /* ... */ iram = <&ocram>; }; Changes since v4: - Added Matt Porter's patch to configure alloc order, so that the driver can be used for TI Davinci. - Removed device tree patches as those should go through the ARM SoC tree. regards Philipp --- Documentation/devicetree/bindings/misc/sram.txt | 27 + drivers/misc/Kconfig|9 ++ drivers/misc/Makefile |1 + drivers/misc/sram.c | 133 +++ include/linux/genalloc.h| 14 +++ include/linux/platform_data/sram.h | 25 + lib/genalloc.c | 67 7 files changed, 276 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 4/4] misc: sram: add support for configurable allocation order
From: Matt Porter Adds support for setting the genalloc pool's minimum allocation order via DT or platform data. The allocation order is optional for both the DT property and platform data case. If it is not present then the order defaults to PAGE_SHIFT to preserve the current behavior. Signed-off-by: Matt Porter Signed-off-by: Philipp Zabel --- Documentation/devicetree/bindings/misc/sram.txt | 12 ++- drivers/misc/sram.c | 14 - include/linux/platform_data/sram.h | 25 +++ 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 include/linux/platform_data/sram.h diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt index b64136c..b1705ec 100644 --- a/Documentation/devicetree/bindings/misc/sram.txt +++ b/Documentation/devicetree/bindings/misc/sram.txt @@ -8,10 +8,20 @@ Required properties: - reg : SRAM iomem address range -Example: +Optional properties: + +- alloc-order : Minimum allocation order for the SRAM pool + +Examples: + +sram: sram@5c00 { + compatible = "sram"; + reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ +}; sram: sram@5c00 { compatible = "sram"; reg = <0x5c00 0x4>; /* 256 KiB SRAM at address 0x5c00 */ + alloc-order = <9>; /* Minimum 512 byte allocation */ }; diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 0cc2e75..3a04b77 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -28,6 +28,7 @@ #include #include #include +#include struct sram_dev { struct gen_pool *pool; @@ -40,6 +41,7 @@ static int __devinit sram_probe(struct platform_device *pdev) struct sram_dev *sram; struct resource *res; unsigned long size; + u32 alloc_order = PAGE_SHIFT; int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -60,7 +62,17 @@ static int __devinit sram_probe(struct platform_device *pdev) if (!IS_ERR(sram->clk)) clk_prepare_enable(sram->clk); - sram->pool = gen_pool_create(PAGE_SHIFT, -1); + if (pdev->dev.of_node) + of_property_read_u32(pdev->dev.of_node, +"alloc-order", &alloc_order); + else + if (pdev->dev.platform_data) { + struct sram_pdata *pdata = pdev->dev.platform_data; + if (pdata->alloc_order) + alloc_order = pdata->alloc_order; + } + + sram->pool = gen_pool_create(alloc_order, -1); if (!sram->pool) return -ENOMEM; diff --git a/include/linux/platform_data/sram.h b/include/linux/platform_data/sram.h new file mode 100644 index 000..e17bdaa --- /dev/null +++ b/include/linux/platform_data/sram.h @@ -0,0 +1,25 @@ +/* + * include/linux/platform_data/sram.h + * + * Platform data for generic sram driver + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SRAM_H_ +#define _SRAM_H_ + +struct sram_pdata { + unsigned alloc_order; /* Optional: driver defaults to PAGE_SHIFT */ +}; + +#endif /* _SRAM_H_ */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] drbd Kconfig update and minor fixes
The following changes since commit 84ad6845fbb1248228d3beab8084e4b5f6f82b1d: Merge branch 'stable/for-jens-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen into for-3.8/drivers (2012-12-01 09:42:41 +0100) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens for you to fetch changes up to d2ec180c23a5a1bfe34d8638b0342a47c00cf70f: drbd: update Kconfig to match current dependencies (2012-12-06 13:08:29 +0100) Lars Ellenberg (2): drbd: respect no-md-barriers setting also when changed online via disk-options drbd: update Kconfig to match current dependencies Philipp Reisner (3): drbd: Remove obsolete check drbd: close race between drbd_set_role and drbd_connect drbd: Fix drbdsetup wait-connect, wait-sync etc... commands drivers/block/drbd/Kconfig | 10 ++ drivers/block/drbd/drbd_main.c |2 +- drivers/block/drbd/drbd_nl.c | 16 +++- drivers/block/drbd/drbd_receiver.c | 10 ++ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/block/drbd/Kconfig b/drivers/block/drbd/Kconfig index df09837..7845bd6 100644 --- a/drivers/block/drbd/Kconfig +++ b/drivers/block/drbd/Kconfig @@ -2,13 +2,14 @@ # DRBD device driver configuration # -comment "DRBD disabled because PROC_FS, INET or CONNECTOR not selected" - depends on PROC_FS='n' || INET='n' || CONNECTOR='n' +comment "DRBD disabled because PROC_FS or INET not selected" + depends on PROC_FS='n' || INET='n' config BLK_DEV_DRBD tristate "DRBD Distributed Replicated Block Device support" - depends on PROC_FS && INET && CONNECTOR + depends on PROC_FS && INET select LRU_CACHE + select LIBCRC32C default n help @@ -58,7 +59,8 @@ config DRBD_FAULT_INJECTION 32data read 64read ahead 128 kmalloc of bitmap - 256 allocation of EE (epoch_entries) + 256 allocation of peer_requests + 512 insert data corruption on receiving side fault_devs: bitmask of minor numbers fault_rate: frequency in percent diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 52de26d..8c13eeb 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -840,7 +840,7 @@ int _drbd_send_uuids(struct drbd_conf *mdev, u64 uuid_flags) } spin_lock_irq(&mdev->ldev->md.uuid_lock); for (i = UI_CURRENT; i < UI_SIZE; i++) - p->uuid[i] = mdev->ldev ? cpu_to_be64(mdev->ldev->md.uuid[i]) : 0; + p->uuid[i] = cpu_to_be64(mdev->ldev->md.uuid[i]); spin_unlock_irq(&mdev->ldev->md.uuid_lock); mdev->comm_bm_set = drbd_bm_total_weight(mdev); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 76bb3a6..2af26fc 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1230,6 +1230,11 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) else mdev->ldev->md.flags |= MDF_AL_DISABLED; + if (new_disk_conf->md_flushes) + clear_bit(MD_NO_FUA, &mdev->flags); + else + set_bit(MD_NO_FUA, &mdev->flags); + drbd_bump_write_ordering(mdev->tconn, WO_bdev_flush); drbd_md_sync(mdev); @@ -3292,11 +3297,12 @@ void drbd_bcast_event(struct drbd_conf *mdev, const struct sib_info *sib) unsigned seq; int err = -ENOMEM; - if (sib->sib_reason == SIB_SYNC_PROGRESS && - time_after(jiffies, mdev->rs_last_bcast + HZ)) - mdev->rs_last_bcast = jiffies; - else - return; + if (sib->sib_reason == SIB_SYNC_PROGRESS) { + if (time_after(jiffies, mdev->rs_last_bcast + HZ)) + mdev->rs_last_bcast = jiffies; + else + return; + } seq = atomic_inc_return(&drbd_genl_seq); msg = genlmsg_new(NLMSG_GOODSIZE, GFP_NOIO); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 1599a1a..a9eccfc 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1037,6 +1037,16 @@ randomize: rcu_read_lock(); idr_for_each_entry(&tconn->volumes, mdev, vnr) { kref_get(&mdev->kref); + /* Prevent a race between resync-handshake and +* being promoted to Primary. +* +* Grab and release the state mutex, so we know that any current +* drbd_set_role() is fin
Re: [PATCH v5 4/4] misc: sram: add support for configurable allocation order
Am Mittwoch, den 14.11.2012, 19:15 + schrieb Grant Likely: > On Thu, 18 Oct 2012 16:27:33 +0200, Philipp Zabel > wrote: > > From: Matt Porter > > > > Adds support for setting the genalloc pool's minimum allocation > > order via DT or platform data. The allocation order is optional > > for both the DT property and platform data case. If it is not > > present then the order defaults to PAGE_SHIFT to preserve the > > current behavior. > > > > Signed-off-by: Matt Porter > > Signed-off-by: Philipp Zabel > > --- > > Documentation/devicetree/bindings/misc/sram.txt | 12 ++- > > drivers/misc/sram.c | 14 - > > include/linux/platform_data/sram.h | 25 > > +++ > > 3 files changed, 49 insertions(+), 2 deletions(-) > > create mode 100644 include/linux/platform_data/sram.h > > > > diff --git a/Documentation/devicetree/bindings/misc/sram.txt > > b/Documentation/devicetree/bindings/misc/sram.txt > > index b64136c..b1705ec 100644 > > --- a/Documentation/devicetree/bindings/misc/sram.txt > > +++ b/Documentation/devicetree/bindings/misc/sram.txt > > @@ -8,10 +8,20 @@ Required properties: > > > > - reg : SRAM iomem address range > > > > -Example: > > +Optional properties: > > + > > +- alloc-order : Minimum allocation order for the SRAM pool > > Looks okay, but I think the property name is confusing. I for one had > no idea what 'order' would be and why it was important. I had to read > the code to figure it out. > > It does raise the question though of what is this binding actually > for? Does it reflect a limitation of the SRAM? or of the hardware using > the SRAM? Or is it an optimization? How do you expect to use it? If I am not mistaken, it is about the expected use case. A driver allocating many small buffers would quickly fill small SRAMs if the allocations were of PAGE_SIZE granularity. I wonder if a common allocation size (say, 512 bytes instead of PAGE_SIZE) can be found that every prospective user could be reasonably happy with? > Assuming it is appropriate to put into the device tree, I'd suggest a > different name. Instead of 'order', how about 'sram-alloc-align' (in > address bits) or 'sram-alloc-min-size' (in bytes). A size in bytes would be the most obvious to me, although that allows to enter values that are not a power of two. regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5 1/4] genalloc: add a global pool list, allow to find pools by phys address
Hi Paul, Am Freitag, den 26.10.2012, 15:46 -0400 schrieb Paul Gortmaker: > On Thu, Oct 18, 2012 at 10:27 AM, Philipp Zabel > wrote: > > This patch keeps all created pools in a global list and adds two > > functions that allow to retrieve the gen_pool pointer from a known > > physical address and from a device tree node. > > So, I'm not seeing any added users of the of_get_named_gen_pool, > or the other exported "reverse-lookup" function. Without that, the > anticipated use case is not clear to me. My use case is the coda video codec driver, for a video codec IP core that is integrated in various SoCs. It can use on-SoC SRAM as temporary memory. Other possible use cases are the TI Davinci sound driver. Or the PXA frame buffer driver could allocate a frame buffer in SRAM for low-resolution devices. > Is there an example of some pending driver or similar, that has > a phys addr from an unknown source and needs to know what > pool it may or may not be in? With the use case, someone might > be able to suggest alternative ways to get what you want done. drivers/media/platform/coda.c right now uses imx specific iram_alloc/free wrappers around gen_pool_alloc/free. I'd like to use of_get_named_gen_pool to obtain the struct gen_pool pointer and use gen_pool_alloc/free directly, instead. sound/soc/davinci/davinci-pcm.c right now uses davinci specific sram_alloc/free wrappers around gen_pool_alloc/free. drivers/dma/mmp_tdma.c and sound/soc/pxa/mmp-pcm.c already use gen_pool_alloc/free directly, but they use a arch-mmp specific sram_get_gpool function to obtain the struct gen_pool pointer. > It might also be worth cross compiling this for powerpc, since the > header files you implicitly get included varies from one arch to > the next, and there might be some compile fails lurking there. Thanks, I'll do that. regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] drbd-8.4.2 for the linux-3.8 merge window
Hi Jens, Please pull drbd-8.4.2 into your for-3.8/drivers branch. The most noticeable change is the support for multiple replicated volumes in a single DRBD connection. This release requires new drbd userland tools >= 8.4.0 (available since July 2011). 8.4.x is network protocol compatible with all previous releaes. This release brings a new meta-data format. Forward (8.3 -> 8.4) conversion happens complete seamless. Backward conversion is done by a single command (drbdadm apply-al res). The "recent changes" chapter of our user's guide describes all changes in detail: http://www.drbd.org/users-guide/ap-recent-changes.html Changelog 8.4.2 (api:genl1/proto:86-100) * Go into inconsistent disk state with on-io-error=pass-on policy * Timeouts for requests processing on the peer (previously that worked only if the data socket was congested) * Conflicting write detection is now based on an interval tree, removed the hash-tables (necessary for the unlimited BIO sizes) * Support for multiple volumes (minors, block devices) per connection; up to 65536 volumes per connection supported * Reduced IO latencies during some state changes (esp. start resync) * New on disk format for the AL: double capacity; 4k aligned IO; same space * Multiple AL changes in a single transaction (precondition for unlimited BIO sizes) * DRBD no longer imposes any limit on BIO sizes * Removed DRBD's limits on the number of minor devices * DRBD's minors can now be removed (not only unconfigured) * Switched the user space interface form connector to generic netlink * The wire-protocol is now a regular connection option, which can be changed while the device is online * IO freezing/thawing is done on connection (all volumes) level * fencing is done on connection (all volumes) level * Enforce application of activity log after primary crash in user space * New default values (compared to drbd-8.3) for: minor-count, ko-count, al-extents, c-plan-ahead, c-fill-target, c-min-rate, use-rle, on-io-error * Optional load balancing for read requests: new keyword "read-balance" * New option 'al-updates no' to disable writing transactions into the activity log. It is use full if you prefer a full sync after a primary crash, for improved performance of a spread out random write work load * Expose the data generation identifies via sysfs Jens, regarding the code: It has the sysfs bits in again. The reason for that is that we want to expose more information by that, and remove the /proc/drbd with the next evolutionary step. -- In case this is a show stopper, let me remove the sysfs bits. Here is the git-pull-request test: (The patch subjects removed to make the mail more digestible) The following changes since commit ccae7868b0c5697508a541c531cf96b361d62c1c: drbd: log request sector offset and size for IO errors (2012-10-30 08:39:18 +0100) are available in the git repository at: git://git.drbd.org/linux-drbd.git for-jens_drbd-8.4.2 for you to fetch changes up to e877f7fdc0b1052b0e881e61f9290268eb21aa2f: drbd: use copy_highpage (2012-11-09 12:06:44 +0100) Akinobu Mita (1): drbd: use copy_highpage Andreas Gruenbacher (210): drbd: Get rid of req_validator_fn typedef [...] David Howells (1): DRBD: Fix comparison always false warning due to long/long long compare Jing Wang (1): drbd: check return of kmalloc in receive_uuids Lars Ellenberg (138): drbd: simplify condition in drbd_may_do_local_read() [...] Philipp Marek (1): drbd: pass some more information to userspace. Philipp Reisner (234): idr: idr_for_each_entry() macro [...] drivers/block/drbd/Makefile|2 + drivers/block/drbd/drbd_actlog.c | 689 +++ drivers/block/drbd/drbd_bitmap.c | 227 ++- drivers/block/drbd/drbd_int.h | 1399 ++--- drivers/block/drbd/drbd_interval.c | 207 ++ drivers/block/drbd/drbd_interval.h | 40 + drivers/block/drbd/drbd_main.c | 3918 ++-- drivers/block/drbd/drbd_nl.c | 3391 ++- drivers/block/drbd/drbd_nla.c | 55 + drivers/block/drbd/drbd_nla.h |8 + drivers/block/drbd/drbd_proc.c | 33 +- drivers/block/drbd/drbd_receiver.c | 3883 --- drivers/block/drbd/drbd_req.c | 1569 +++ drivers/block/drbd/drbd_req.h | 187 +- drivers/block/drbd/drbd_state.c| 1857 + drivers/block/drbd/drbd_state.h| 161 ++ drivers/block/drbd/drbd_strings.c |1 + drivers/block/drbd/drbd_sysfs.c| 86 + drivers/block/drbd/drbd_worker.c | 1168 ++- drivers/block/drbd/drbd_wrappers.h | 11 +- include/linux/drbd.h | 81 +- include/linux/drbd_genl.h | 378 include/linux/drbd_genl_api.h
Re: [GIT PULL] drbd-8.4.2 for the linux-3.8 merge window
[...] > > It has the sysfs bits in again. The reason for that is that we want to > > expose more information by that, and remove the /proc/drbd with the > > next evolutionary step. -- In case this is a show stopper, let me > > remove the sysfs bits. > > The exact same sysfs bits I complained about last time? If yes, then I > don't understand why you haven't changed yet. Or why you are trying to > push the same bits again that got rejected last time. > I had the impression it was rejected because I submitted the pull request too late to you. In the sense of, it might go in, if it gets submitted for inclusion before the merge window opens... Apparently my impression was wrong. You will get an updated pull-request with the sysfs bits removed > > Here is the git-pull-request test: > > (The patch subjects removed to make the mail more digestible) > > Please don't do that, it basically makes the pull request useless! A few > hundred extra lines is not an issue. Ok. I intend to send the updated pull-request later today. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] drbd-8.4.2 for the linux-3.8 merge window
o: properly initialize page->private drbd: grammar fix in log message drbd: fix access of unallocated pages and kernel panic drbd: fix local read error hung forever drbd: fix wrong assert in completion/retry path of failed local reads drbd: rename drbd_restart_write to drbd_restart_request drbd: transfer log epoch numbers are now per resource drbd: allow to dequeue batches of work at a time drbd: move the drbd_work_queue from drbd_socket to drbd_connection drbd: remove struct drbd_tl_epoch objects (barrier works) drbd: better separate WRITE and READ code paths in drbd_make_request drbd: __drbd_make_request() is now void drbd: introduce completion_ref and kref to struct drbd_request drbd: base completion and destruction of requests on ref counts drbd: __req_mod: make DISCARD_WRITE and independend case drbd: allow read requests to be retried after force-detach drbd: take error path in drbd_adm_down if interrupted by signal drbd: fix null pointer dereference with on-congestion policy when diskless drbd: cleanup, remove two unused global flags drbd: differentiate between normal and forced detach drbd: report congestion if we are waiting for some userland callback drbd: reset congestion information before reporting it in /proc/drbd drbd: do not reset rs_pending_cnt too early drbd: call local-io-error handler early drbd: flush drbd work queue before invalidate/invalidate remote drbd: introduce stop-sector to online verify drbd: announce FLUSH/FUA capability to upper layers drbd: fix drbd wire compatibility for empty flushes drbd: Fix a potential issue with the DISCARD_CONCURRENT flag drbd: only start a new epoch, if the current epoch contains writes drbd: NEG_ACK does not imply a barrier-ack drbd: cleanup, drop unused struct drbd: disambiguation, s/P_DISCARD_WRITE/P_SUPERSEDED/ drbd: disambiguation, s/DISCARD_CONCURRENT/RESOLVE_CONFLICTS/ drbd: disambiguation, s/ERR_DISCARD/ERR_DISCARD_IMPOSSIBLE/ drbd: properly call drbd_rs_cancel_all() in drbd_disconnected() drbd: don't send out P_BARRIER with stale information drbd: temporarily suspend io in drbd_adm_disk_opts drbd: mutex_unlock "... must no be used in interrupt context" drbd: dequeue single work items in wait_for_work() drbd: fix potential list_add corruption drbd: differentiate early and later "postponing" of requests drbd: use list_move_tail instead of list_del/list_add_tail drbd: fix potential deadlock during bitmap (re-)allocation drbd: a few more GFP_KERNEL -> GFP_NOIO drbd: wait for meta data IO completion even with failed disk, unless force-detached drbd: always write bitmap on detach drbd: log request sector offset and size for IO errors drbd: if the replication link breaks during handshake, keep retrying Philipp Marek (1): drbd: pass some more information to userspace. Philipp Reisner (232): idr: idr_for_each_entry() macro drbd: Minimal struct drbd_tconn drbd: moved net_conf from mdev to tconn drbd: moved net_cont and net_cnt_wait from mdev to tconn drbd: moved data and meta from mdev to tconn drbd: moved receiver, worker and asender from mdev to tconn drbd: moved agreed_pro_version, last_received and ko_count to tconn drbd: moved req_lock and transfer log from mdev to tconn drbd: moved crypto transformations and friends from mdev to tconn drbd: Made drbd_flush_workqueue() to take a tconn instead of an mdev drbd: Preparing to use p_header96 for all packets drbd: Replaced all p_header80 with a generic p_header drbd: Use new header layout drbd: Implemented receiving of new style packets on meta socket drbd: Do not access tconn after it was freed drbd: Moved the state functions into its own source file drbd: Moved the thread name into the data structure drbd: Eliminated the user of drbd_task_to_thread() drbd: Moved code drbd: Do no sleep long in drbd_start_resync drbd: Revert "Make sure we dont send state if a cluster wide state change is in progress" drbd: Moving state related macros to drbd_state.h drbd: conn_printk() a dev_printk() alike for drbd's connections drbd: Converted drbd_try_connect() from mdev to tconn drbd: Converted drbd_wait_for_connect() from mdev to tconn drbd: Started to separated connection flags (tconn) from block device flags (mdev) drbd: Moved DISCARD_CONCURRENT to the per connection (tconn) flags drbd: Moved SEND_PING to the per connection (tconn) flags drbd: Moved SIGNAL_ASENDER to the per connection (tconn) flags drbd: Converted wake_asender() and request_ping() from mdev to tconn drbd: Converted hel
Re: [GIT PULL] drbd-8.4.2 for the linux-3.8 merge window
Am Freitag, 9. November 2012, 15:50:24 schrieb Jens Axboe: > On 2012-11-09 15:18, Jens Axboe wrote: > > On 2012-11-09 14:33, Philipp Reisner wrote: > >> Jens, here it is without the sysfs stuff > > > > Thanks, pulled into for-3.8/drivers > > I didn't say anything, but I've been fuming a bit the last few series of > merge windows. You need to stop these insanely massive pull requests. > I've been large since this is "just a driver", but it can't continue. We > should have reached stability a long time ago. Your pull requests > contain a shit load of items, are you guys paying per commit? Look at > these: > > drbd: Request lookup code cleanup (1) > drbd: Request lookup code cleanup (2) > drbd: Request lookup code cleanup (3) > drbd: Request lookup code cleanup (4) > We are living there in the belief that we should break up big changes in review able chunks > or > > drbd: conn_send_cmd2(): Return 0 upon success and an error code > otherwise drbd: _conn_send_cmd(): Return 0 upon success and an error code > otherwise drbd: _drbd_send_cmd(): Return 0 upon success and an error code > otherwise drbd: conn_send_cmd(): Return 0 upon success and an error code > otherwise > Function by function gets converted to the "return 0 upon success" call semantics. Do you prefer that all of that should be done in a single commit? > along with FIFTY or so more of these. WTF is this? > > drbd: Converted helper functions for drbd_send() to tconn > drbd: Converted drbd_send() from mdev to tconn > drbd: Converted drbd_send_fp() from mdev to tconn > Should it instead be in a single commit? > > I don't think I need to go on. So from now on, to get items into the > kernel, what you will do is: > > - Stop doing insane commits like the above. It just doesn't make sense. > > - Send pull requests in a timely fashion. No more of this "lets collect > ALL the things" then send it off. Collect small bug fixes, send those > off. Develop some feature or make some changes, send that off. Etc. That works well for individual features, and we have been doing that for the last two Years. But at this time we changed the object model. In the old code we had a single kind of DRBD-in-kernel-object: a resource Now we have two kinds: resources and volumes. 8.3: a resource had a single implicit volume 8.4: a resource might contain multiple volumes, each volume belongs to a single resource. In the next ~12 month you will get only small features/updates etc... for the 8.4 code base. > The fact that your initial pull request had to MASK all these commits > should have rung big bells in your head. It's a clear sign of a huge > problem in your development model. If you can't clean this up, then > it's not going in. Fundamental changes in our object model require such huge change sets. Jens, we will not stop where we are today. We plan to introduce a new object: a connection. (The ability to mirror for one machine to *multiple* receivers.) Is it a better fit to introduce it then as a new driver? E.g. called it "drbd9". Should it use a new major number? Best, Phil -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/