Commit ed08e6df authored by Bernardo Innocenti's avatar Bernardo Innocenti Committed by Linus Torvalds

[PATCH] asm-generic/div64.h breakage

 - __div64_32(): remove __attribute_pure__ qualifier from the prototype
   since this function obviously clobbers memory through &(n);

 - do_div(): add a check to ensure (n) is type-compatible with uint64_t;

 - as_update_iohist(): Use sector_div() instead of do_div().
   (Whether the result of the addition should always be stored in 64bits
   regardless of CONFIG_LBD is still being discussed, therefore it's
   unadderessed here);

 - Fix all places where do_div() was being called with a bad divisor argument.
parent 963436f3
...@@ -837,7 +837,7 @@ static void as_update_iohist(struct as_io_context *aic, struct request *rq) ...@@ -837,7 +837,7 @@ static void as_update_iohist(struct as_io_context *aic, struct request *rq)
aic->seek_total += 256*seek_dist; aic->seek_total += 256*seek_dist;
if (aic->seek_samples) { if (aic->seek_samples) {
aic->seek_mean = aic->seek_total + 128; aic->seek_mean = aic->seek_total + 128;
do_div(aic->seek_mean, aic->seek_samples); sector_div(aic->seek_mean, aic->seek_samples);
} }
aic->seek_samples = (aic->seek_samples>>1) aic->seek_samples = (aic->seek_samples>>1)
+ (aic->seek_samples>>2); + (aic->seek_samples>>2);
......
...@@ -32,11 +32,15 @@ ...@@ -32,11 +32,15 @@
#elif BITS_PER_LONG == 32 #elif BITS_PER_LONG == 32
extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor) __attribute_pure__; extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
/* The unnecessary pointer compare is there
* to check for type safety (n must be 64bit)
*/
# define do_div(n,base) ({ \ # define do_div(n,base) ({ \
uint32_t __base = (base); \ uint32_t __base = (base); \
uint32_t __rem; \ uint32_t __rem; \
(void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
if (likely(((n) >> 32) == 0)) { \ if (likely(((n) >> 32) == 0)) { \
__rem = (uint32_t)(n) % __base; \ __rem = (uint32_t)(n) % __base; \
(n) = (uint32_t)(n) / __base; \ (n) = (uint32_t)(n) / __base; \
......
...@@ -127,7 +127,7 @@ static int skip_atoi(const char **s) ...@@ -127,7 +127,7 @@ static int skip_atoi(const char **s)
#define SPECIAL 32 /* 0x */ #define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type) static char * number(char * buf, char * end, unsigned long long num, int base, int size, int precision, int type)
{ {
char c,sign,tmp[66]; char c,sign,tmp[66];
const char *digits; const char *digits;
......
...@@ -147,7 +147,7 @@ static int shrink_slab(long scanned, unsigned int gfp_mask) ...@@ -147,7 +147,7 @@ static int shrink_slab(long scanned, unsigned int gfp_mask)
pages = nr_used_zone_pages(); pages = nr_used_zone_pages();
list_for_each_entry(shrinker, &shrinker_list, list) { list_for_each_entry(shrinker, &shrinker_list, list) {
long long delta; unsigned long long delta;
delta = scanned * shrinker->seeks; delta = scanned * shrinker->seeks;
delta *= (*shrinker->shrinker)(0, gfp_mask); delta *= (*shrinker->shrinker)(0, gfp_mask);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment