On Mon, 2011-07-25 at 16:50 -0700, Andrew Morton wrote: > On Mon, 25 Jul 2011 16:37:39 -0700 > Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote: > > > On Sat, 23 Jul 2011 16:16:15 -0700 > > "Nicholas A. Bellinger" <nab@xxxxxxxxxxxxxxx> wrote: > > > > > Please go ahead and pull from: > > > > > > master.kernel.org:/pub/scm/linux/kernel/git/nab/target-pending.git for-linus-merge > > > > i386 allyesconfig: > > > > ERROR: "__udivdi3" [drivers/target/target_core_mod.ko] undefined! > > > > somewhere in drivers/target/target_core_transport.c:transport_allocate_data_tasks(). > > Probably the best place to fix this is within DIV_ROUND_UP(): make it > handle 64-bits on 32-bit. > > This will have the pleasing side-effect of breaking > drivers/scsi/cxgbi/cxgb4i/cxgb4i.c, which felt a need to duplicate the > existing DIV_ROUND_UP() implementation. > Thanks for the input everyone. :) How about the following to add a new DIV_ROUND_UP_ULL macro, and enable it's usage within the offending transport_allocate_data_tasks() change causing the regression in question for target_core_mod..? Is there anything else that should be done to avoid unnecessary 64-bit divide instruction slowness for generic 32-bit arch operation here..? Thank you, --nab diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index a244c90..8032e1e 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -4054,17 +4054,16 @@ static int transport_allocate_data_tasks( struct se_task *task; struct se_device *dev = cmd->se_dev; unsigned long flags; - sector_t sectors; int task_count, i, ret; - sector_t dev_max_sectors = dev->se_sub_dev->se_dev_attrib.max_sectors; + sector_t sectors, dev_max_sectors = dev->se_sub_dev->se_dev_attrib.max_sectors; u32 sector_size = dev->se_sub_dev->se_dev_attrib.block_size; struct scatterlist *sg; struct scatterlist *cmd_sg; WARN_ON(cmd->data_length % sector_size); sectors = DIV_ROUND_UP(cmd->data_length, sector_size); - task_count = DIV_ROUND_UP(sectors, dev_max_sectors); - + task_count = DIV_ROUND_UP_ULL(sectors, dev_max_sectors); + cmd_sg = sgl; for (i = 0; i < task_count; i++) { unsigned int task_size; diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 953352a..d66cba7 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -56,6 +56,17 @@ #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define DIV_ROUND_UP_ULL(n,d) ( \ +{ \ + unsigned long long _tmp = n, _off; \ + int _res; \ + /* Round up using asm/div64.h:do_div */ \ + _off = do_div(_tmp, d); \ + if (_off != 0) \ + _tmp++; \ + _res = _tmp; \ +} \ +) /* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */ #define roundup(x, y) ( \ -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html