lkml.org 
[lkml]   [2019]   [Jul]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH] be2net: fix adapter->big_page_size miscaculation
From
Date
The original issue,

https://lore.kernel.org/netdev/1562959401-19815-1-git-send-email-cai@lca.pw/

The debugging so far seems point to that the compilers get confused by the
module sections. During module_param(), it stores “__param_rx_frag_size"
as a “struct kernel_param” into the __param section. Later, load_module()
obtains all “kernel_param” from the __param section and compare against the
user-input module parameters from the command-line. If there is a match, it
calls params[i].ops->set(&params[I]) to replace the value. If compilers can’t
see that params[i].ops->set(&params[I]) could potentially change the value
of rx_frag_size, it will wrongly optimize it as a constant.


For example (it is not
compilable yet as I have not able to extract variable from the __param section
like find_module_sections()),

#include <stdio.h>
#include <string.h>

#define __module_param_call(name, ops, arg) \
static struct kernel_param __param_##name \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) = { \
#name, ops, { arg } }

struct kernel_param {
const char *name;
const struct kernel_param_ops *ops;
union {
int *arg;
};
};

struct kernel_param_ops {
int (*set)(const struct kernel_param *kp);
};

#define STANDARD_PARAM_DEF(name) \
int param_set_##name(const struct kernel_param *kp) \
{ \
*kp->arg = 2; \
} \
const struct kernel_param_ops param_ops_##name = { \
.set = param_set_##name, \
};

STANDARD_PARAM_DEF(ushort);
static int rx = 1;
__module_param_call(rx_frag_siz, &param_ops_ushort, &rx_frag_size);

int main(int argc, char *argv[])
{
const struct kernel_param *params = <<< Get all kernel_param from the __param section >>>;
int i;

if (__builtin_constant_p(rx_frag_size))
printf("rx_frag_size is a const.\n");

for (i = 0; i < num_param; i++) {
if (!strcmp(params[I].name, argv[1])) {
params[i].ops->set(&params[i]);
break;
}
}

printf("rx_frag_size = %d\n", rx_frag_size);

return 0;
}

\
 
 \ /
  Last update: 2019-07-23 05:10    [W:0.054 / U:2.280 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site