Re: [PATCH V2] usb: xhci: add support for performing fake doorbell
Hi Mathias, On 17 October 2016 at 22:30, Rafał Miłeckiwrote: > From: Rafał Miłecki > > Broadcom's Northstar XHCI controllers seem to need a special start > procedure to work correctly. There isn't any official documentation of > this, the problem is that controller doesn't detect any connected > devices with default setup. Moreover connecting USB device to controller > that doesn't run properly can cause SoC's watchdog issues. > > A workaround that was successfully tested on multiple devices is to > perform a fake doorbell. This patch adds code for doing this and enables > it on BCM4708 family. > > Signed-off-by: Rafał Miłecki > --- > V2: Enable quirk for brcm,bcm4708 machines instead of adding separated binding > for it. Thanks Rob for your comment on this. Do you think you can pick & push this one? V2 follows Rob's suggestion and he has some DT knowledge for sure, so I guess it should be OK.
Re: [PATCH V2] usb: xhci: add support for performing fake doorbell
Hi Mathias, On 17 October 2016 at 22:30, Rafał Miłecki wrote: > From: Rafał Miłecki > > Broadcom's Northstar XHCI controllers seem to need a special start > procedure to work correctly. There isn't any official documentation of > this, the problem is that controller doesn't detect any connected > devices with default setup. Moreover connecting USB device to controller > that doesn't run properly can cause SoC's watchdog issues. > > A workaround that was successfully tested on multiple devices is to > perform a fake doorbell. This patch adds code for doing this and enables > it on BCM4708 family. > > Signed-off-by: Rafał Miłecki > --- > V2: Enable quirk for brcm,bcm4708 machines instead of adding separated binding > for it. Thanks Rob for your comment on this. Do you think you can pick & push this one? V2 follows Rob's suggestion and he has some DT knowledge for sure, so I guess it should be OK.
Re: [RFC][PATCH 7/7] kref: Implement using refcount_t
* Boqun Fengwrote: > > It also fails to decrement in the underflow case (which is fine, but not > > obvious from the comment). Same thing below. > > > > Maybe a table in the comment like the following helps? > > /* > * T: return true, F: return fasle > * W: trigger WARNING > * N: no effect > * > * | value before ops | > * | 0 | 1 | UINT_MAX - 1 | UINT_MAX | > * -+---+---+--+--+ > * inc()| W| | W | N | > * inc_not_zero() | FN | T | WT |WTN | > * dec_and_test() | WFN | T | F | FN | > * dec_and_mutex_lock() | WFN | T | F | FN | > * dec_and_spin_lock() | WFN | T | F | FN | > */ Yes! nit: s/fasle/false Also, I think we want to do a couple of other changes as well to make it more readable, extend the columns with 'normal' values (2 and UINT_MAX-2) and order the colums properly. I.e. something like: /* * The before/after outcome of various atomic ops: * * T: returns true * F: returns false * -- * W: op triggers kernel WARNING * -- * 0: no change to atomic var value * +: atomic var value increases by 1 * -: atomic var value decreases by 1 * -- * -1: UINT_MAX * -2: UINT_MAX-1 * -3: UINT_MAX-2 * * -+-+-+-+-+-+-+ * value before:| -3 | -2 | -1 | 0 | 1 | 2 | * -+-+-+-+-+-+-+ * value+effect after: | * -+ | | | | | | * inc()| ..+ | W.+ | ..0 | W.+ | ..+ | ..+ | * inc_not_zero() | .T+ | WT+ | WT0 | .F0 | .T+ | .T+ | * dec_and_test() | .F- | .F- | .F0 | WF0 | .T- | .F- | * dec_and_mutex_lock() | .F- | .F- | .F0 | WF0 | .T- | .F- | * dec_and_spin_lock() | .F- | .F- | .F0 | WF0 | .T- | .F- | * -+-+-+-+-+-+-+ * * So for example: 'WT+' in the inc_not_zero() row and '-2' column * means that when the atomic_inc_not_zero() function is called * with an atomic var that has a value of UINT_MAX-1, then the * atomic var's value will increase to the maximum overflow value * of UINT_MAX and will produce a warning. The function returns * 'true'. */ I think this table makes the overflow/underflow semantics pretty clear and also documents the regular behavior of these atomic ops pretty intuitively. Agreed? Thanks, Ingo
Re: [RFC][PATCH 7/7] kref: Implement using refcount_t
* Boqun Feng wrote: > > It also fails to decrement in the underflow case (which is fine, but not > > obvious from the comment). Same thing below. > > > > Maybe a table in the comment like the following helps? > > /* > * T: return true, F: return fasle > * W: trigger WARNING > * N: no effect > * > * | value before ops | > * | 0 | 1 | UINT_MAX - 1 | UINT_MAX | > * -+---+---+--+--+ > * inc()| W| | W | N | > * inc_not_zero() | FN | T | WT |WTN | > * dec_and_test() | WFN | T | F | FN | > * dec_and_mutex_lock() | WFN | T | F | FN | > * dec_and_spin_lock() | WFN | T | F | FN | > */ Yes! nit: s/fasle/false Also, I think we want to do a couple of other changes as well to make it more readable, extend the columns with 'normal' values (2 and UINT_MAX-2) and order the colums properly. I.e. something like: /* * The before/after outcome of various atomic ops: * * T: returns true * F: returns false * -- * W: op triggers kernel WARNING * -- * 0: no change to atomic var value * +: atomic var value increases by 1 * -: atomic var value decreases by 1 * -- * -1: UINT_MAX * -2: UINT_MAX-1 * -3: UINT_MAX-2 * * -+-+-+-+-+-+-+ * value before:| -3 | -2 | -1 | 0 | 1 | 2 | * -+-+-+-+-+-+-+ * value+effect after: | * -+ | | | | | | * inc()| ..+ | W.+ | ..0 | W.+ | ..+ | ..+ | * inc_not_zero() | .T+ | WT+ | WT0 | .F0 | .T+ | .T+ | * dec_and_test() | .F- | .F- | .F0 | WF0 | .T- | .F- | * dec_and_mutex_lock() | .F- | .F- | .F0 | WF0 | .T- | .F- | * dec_and_spin_lock() | .F- | .F- | .F0 | WF0 | .T- | .F- | * -+-+-+-+-+-+-+ * * So for example: 'WT+' in the inc_not_zero() row and '-2' column * means that when the atomic_inc_not_zero() function is called * with an atomic var that has a value of UINT_MAX-1, then the * atomic var's value will increase to the maximum overflow value * of UINT_MAX and will produce a warning. The function returns * 'true'. */ I think this table makes the overflow/underflow semantics pretty clear and also documents the regular behavior of these atomic ops pretty intuitively. Agreed? Thanks, Ingo
Re: [PATCH 2/5] drm/modes: Support modes names on the command line
Hi Sean, On Wed, Nov 16, 2016 at 12:21:42PM -0500, Sean Paul wrote: > On Tue, Oct 18, 2016 at 4:29 AM, Maxime Ripard >wrote: > > The drm subsystem also uses the video= kernel parameter, and in the > > documentation refers to the fbdev documentation for that parameter. > > > > However, that documentation also says that instead of giving the mode using > > its resolution we can also give a name. However, DRM doesn't handle that > > case at the moment. Even though in most case it shouldn't make any > > difference, it might be useful for analog modes, where different standards > > might have the same resolution, but still have a few different parameters > > that are not encoded in the modes (NTSC vs NTSC-J vs PAL-M for example). > > > > Signed-off-by: Maxime Ripard > > --- > > drivers/gpu/drm/drm_connector.c | 3 +- > > drivers/gpu/drm/drm_fb_helper.c | 4 +++- > > drivers/gpu/drm/drm_modes.c | 49 +++--- > > include/drm/drm_connector.h | 1 +- > > 4 files changed, 41 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_connector.c > > b/drivers/gpu/drm/drm_connector.c > > index 2db7fb510b6c..27a8a511257c 100644 > > --- a/drivers/gpu/drm/drm_connector.c > > +++ b/drivers/gpu/drm/drm_connector.c > > @@ -147,8 +147,9 @@ static void drm_connector_get_cmdline_mode(struct > > drm_connector *connector) > > connector->force = mode->force; > > } > > > > - DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", > > + DRM_DEBUG_KMS("cmdline mode for connector %s %s %dx%d@%dHz%s%s%s\n", > > connector->name, > > + mode->name ? mode->name : "", > > mode->xres, mode->yres, > > mode->refresh_specified ? mode->refresh : 60, > > mode->rb ? " reduced blanking" : "", > > diff --git a/drivers/gpu/drm/drm_fb_helper.c > > b/drivers/gpu/drm/drm_fb_helper.c > > index 03414bde1f15..20a68305fb45 100644 > > --- a/drivers/gpu/drm/drm_fb_helper.c > > +++ b/drivers/gpu/drm/drm_fb_helper.c > > @@ -1748,6 +1748,10 @@ struct drm_display_mode > > *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f > > prefer_non_interlace = !cmdline_mode->interlace; > > again: > > list_for_each_entry(mode, _helper_conn->connector->modes, head) { > > + /* Check (optional) mode name first */ > > + if (!strcmp(mode->name, cmdline_mode->name)) > > + return mode; > > + > > /* check width/height */ > > if (mode->hdisplay != cmdline_mode->xres || > > mode->vdisplay != cmdline_mode->yres) > > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c > > index 7d5bdca276f2..fdbf541a5978 100644 > > --- a/drivers/gpu/drm/drm_modes.c > > +++ b/drivers/gpu/drm/drm_modes.c > > @@ -1413,7 +1413,7 @@ bool drm_mode_parse_command_line_for_connector(const > > char *mode_option, > >struct drm_cmdline_mode > > *mode) > > { > > const char *name; > > - bool parse_extras = false; > > + bool named_mode = false, parse_extras = false; > > unsigned int bpp_off = 0, refresh_off = 0; > > unsigned int mode_end = 0; > > char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; > > @@ -1432,8 +1432,14 @@ bool drm_mode_parse_command_line_for_connector(const > > char *mode_option, > > > > name = mode_option; > > > > + /* > > +* If the first character is not a digit, then it means that > > +* we have a named mode. > > +*/ > > if (!isdigit(name[0])) > > - return false; > > + named_mode = true; > > + else > > + named_mode = false; > > named_mode = isalpha(name[0]); might be more succinct (and covers > special characters). > > > > > /* Try to locate the bpp and refresh specifiers, if any */ > > bpp_ptr = strchr(name, '-'); > > @@ -1460,12 +1466,16 @@ bool > > drm_mode_parse_command_line_for_connector(const char *mode_option, > > parse_extras = true; > > } > > > > - ret = drm_mode_parse_cmdline_res_mode(name, mode_end, > > - parse_extras, > > - connector, > > - mode); > > - if (ret) > > - return false; > > + if (named_mode) { > > + strncpy(mode->name, name, mode_end); > > + } else { > > + ret = drm_mode_parse_cmdline_res_mode(name, mode_end, > > + parse_extras, > > + connector, > > + mode); > > +
Re: [PATCH 2/5] drm/modes: Support modes names on the command line
Hi Sean, On Wed, Nov 16, 2016 at 12:21:42PM -0500, Sean Paul wrote: > On Tue, Oct 18, 2016 at 4:29 AM, Maxime Ripard > wrote: > > The drm subsystem also uses the video= kernel parameter, and in the > > documentation refers to the fbdev documentation for that parameter. > > > > However, that documentation also says that instead of giving the mode using > > its resolution we can also give a name. However, DRM doesn't handle that > > case at the moment. Even though in most case it shouldn't make any > > difference, it might be useful for analog modes, where different standards > > might have the same resolution, but still have a few different parameters > > that are not encoded in the modes (NTSC vs NTSC-J vs PAL-M for example). > > > > Signed-off-by: Maxime Ripard > > --- > > drivers/gpu/drm/drm_connector.c | 3 +- > > drivers/gpu/drm/drm_fb_helper.c | 4 +++- > > drivers/gpu/drm/drm_modes.c | 49 +++--- > > include/drm/drm_connector.h | 1 +- > > 4 files changed, 41 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_connector.c > > b/drivers/gpu/drm/drm_connector.c > > index 2db7fb510b6c..27a8a511257c 100644 > > --- a/drivers/gpu/drm/drm_connector.c > > +++ b/drivers/gpu/drm/drm_connector.c > > @@ -147,8 +147,9 @@ static void drm_connector_get_cmdline_mode(struct > > drm_connector *connector) > > connector->force = mode->force; > > } > > > > - DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", > > + DRM_DEBUG_KMS("cmdline mode for connector %s %s %dx%d@%dHz%s%s%s\n", > > connector->name, > > + mode->name ? mode->name : "", > > mode->xres, mode->yres, > > mode->refresh_specified ? mode->refresh : 60, > > mode->rb ? " reduced blanking" : "", > > diff --git a/drivers/gpu/drm/drm_fb_helper.c > > b/drivers/gpu/drm/drm_fb_helper.c > > index 03414bde1f15..20a68305fb45 100644 > > --- a/drivers/gpu/drm/drm_fb_helper.c > > +++ b/drivers/gpu/drm/drm_fb_helper.c > > @@ -1748,6 +1748,10 @@ struct drm_display_mode > > *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f > > prefer_non_interlace = !cmdline_mode->interlace; > > again: > > list_for_each_entry(mode, _helper_conn->connector->modes, head) { > > + /* Check (optional) mode name first */ > > + if (!strcmp(mode->name, cmdline_mode->name)) > > + return mode; > > + > > /* check width/height */ > > if (mode->hdisplay != cmdline_mode->xres || > > mode->vdisplay != cmdline_mode->yres) > > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c > > index 7d5bdca276f2..fdbf541a5978 100644 > > --- a/drivers/gpu/drm/drm_modes.c > > +++ b/drivers/gpu/drm/drm_modes.c > > @@ -1413,7 +1413,7 @@ bool drm_mode_parse_command_line_for_connector(const > > char *mode_option, > >struct drm_cmdline_mode > > *mode) > > { > > const char *name; > > - bool parse_extras = false; > > + bool named_mode = false, parse_extras = false; > > unsigned int bpp_off = 0, refresh_off = 0; > > unsigned int mode_end = 0; > > char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; > > @@ -1432,8 +1432,14 @@ bool drm_mode_parse_command_line_for_connector(const > > char *mode_option, > > > > name = mode_option; > > > > + /* > > +* If the first character is not a digit, then it means that > > +* we have a named mode. > > +*/ > > if (!isdigit(name[0])) > > - return false; > > + named_mode = true; > > + else > > + named_mode = false; > > named_mode = isalpha(name[0]); might be more succinct (and covers > special characters). > > > > > /* Try to locate the bpp and refresh specifiers, if any */ > > bpp_ptr = strchr(name, '-'); > > @@ -1460,12 +1466,16 @@ bool > > drm_mode_parse_command_line_for_connector(const char *mode_option, > > parse_extras = true; > > } > > > > - ret = drm_mode_parse_cmdline_res_mode(name, mode_end, > > - parse_extras, > > - connector, > > - mode); > > - if (ret) > > - return false; > > + if (named_mode) { > > + strncpy(mode->name, name, mode_end); > > + } else { > > + ret = drm_mode_parse_cmdline_res_mode(name, mode_end, > > + parse_extras, > > + connector, > > + mode); > > + if (ret) > > + return false; > > +
Re: [PATCH v2 2/2] usb: dwc3: core: Support the dwc3 host suspend/resume
Hi Baolin, [auto build test ERROR on next-20161117] [cannot apply to balbi-usb/next usb/usb-testing v4.9-rc6 v4.9-rc5 v4.9-rc4 v4.9-rc6] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Baolin-Wang/usb-host-plat-Enable-xhci-plat-runtime-PM/20161121-143535 config: i386-allmodconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/usb/dwc3/host.c: In function 'dwc3_host_suspend': >> drivers/usb/dwc3/host.c:158:10: error: implicit declaration of function >> 'pm_children_suspended' [-Werror=implicit-function-declaration] while (!pm_children_suspended(xhci) && --cnt > 0) ^ cc1: some warnings being treated as errors vim +/pm_children_suspended +158 drivers/usb/dwc3/host.c 152 int ret, cnt = DWC3_HOST_SUSPEND_COUNT; 153 154 /* 155 * We need make sure the children of the xHCI device had been into 156 * suspend state, or we will suspend xHCI device failed. 157 */ > 158 while (!pm_children_suspended(xhci) && --cnt > 0) 159 msleep(DWC3_HOST_SUSPEND_TIMEOUT); 160 161 if (cnt <= 0) { --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v2 2/2] usb: dwc3: core: Support the dwc3 host suspend/resume
Hi Baolin, [auto build test ERROR on next-20161117] [cannot apply to balbi-usb/next usb/usb-testing v4.9-rc6 v4.9-rc5 v4.9-rc4 v4.9-rc6] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Baolin-Wang/usb-host-plat-Enable-xhci-plat-runtime-PM/20161121-143535 config: i386-allmodconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/usb/dwc3/host.c: In function 'dwc3_host_suspend': >> drivers/usb/dwc3/host.c:158:10: error: implicit declaration of function >> 'pm_children_suspended' [-Werror=implicit-function-declaration] while (!pm_children_suspended(xhci) && --cnt > 0) ^ cc1: some warnings being treated as errors vim +/pm_children_suspended +158 drivers/usb/dwc3/host.c 152 int ret, cnt = DWC3_HOST_SUSPEND_COUNT; 153 154 /* 155 * We need make sure the children of the xHCI device had been into 156 * suspend state, or we will suspend xHCI device failed. 157 */ > 158 while (!pm_children_suspended(xhci) && --cnt > 0) 159 msleep(DWC3_HOST_SUSPEND_TIMEOUT); 160 161 if (cnt <= 0) { --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: moduleparam: introduce core_param_named macro for non-modular code
+++ Paul Gortmaker [14/11/16 21:00 -0500]: We have the case where module_param_named() in file "foo.c" for parameter myparam translates that into the bootarg for the non-modular use case as "foo.myparam=..." The problem exists where the use case with the filename and the dot prefix is established, but the code is then realized to be 100% non-modular, or is converted to non-modular. Both of the existing macros like core_param() or setup_param() do not append such a prefix, so a straight conversion to either will break the existing use cases. Similarly, trying to embed a hard coded "foo." prefix on the name fails cpp syntax due to the special nature of "." in code. So we add this parallel variant for the modular --> non-modular transition to preserve existing and documented use cases with such a prefix. Hm, I'm not convinced we need a core_ counterpart to module_param_named (that's nearly identical), when module_param_named already implements all of the above. Plenty of non-modular code already use it (e.g. workqueue, printk), and a prefix is automatically supplied (which can be overridden) in the non-modular case. That should already meet your requirements, no? Cc: Jessica YuCc: Rusty Russell Signed-off-by: Paul Gortmaker --- [Marking this RFC since I don't like the fact that it still requires non-modular code to use moduleparam.h -- one possible fix for that is to consider moving non-modular macros to a new param.h or similar. ] include/linux/moduleparam.h | 17 + 1 file changed, 17 insertions(+) diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 52666d90ca94..4f2b92345eb5 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -269,6 +269,23 @@ static inline void kernel_param_unlock(struct module *mod) __module_param_call("", name, _ops_##type, , perm, -1, 0) /** + * core_param_named - define a module compat core kernel parameter. + * @name: the name of the cmdline and sysfs parameter (often the same as var) + * @var: the variable + * @type: the type of the parameter + * @perm: visibility in sysfs + * + * core_param_named is just like module_param_named(), but cannot be modular + * and it _does_ add a prefix (such as "printk."). This is for compatibility + * with module_param_named(), and it exists to provide boot arg compatibility + * with code that was previously using the modular version with the prefix. + */ +#define core_param_named(name, var, type, perm) \ + param_check_##type(name, &(var)); \ + __module_param_call(KBUILD_MODNAME ".", name, _ops_##type,\ + , perm, -1, 0) + +/** * core_param_unsafe - same as core_param but taints kernel */ #define core_param_unsafe(name, var, type, perm)\ -- 2.10.1
Re: moduleparam: introduce core_param_named macro for non-modular code
+++ Paul Gortmaker [14/11/16 21:00 -0500]: We have the case where module_param_named() in file "foo.c" for parameter myparam translates that into the bootarg for the non-modular use case as "foo.myparam=..." The problem exists where the use case with the filename and the dot prefix is established, but the code is then realized to be 100% non-modular, or is converted to non-modular. Both of the existing macros like core_param() or setup_param() do not append such a prefix, so a straight conversion to either will break the existing use cases. Similarly, trying to embed a hard coded "foo." prefix on the name fails cpp syntax due to the special nature of "." in code. So we add this parallel variant for the modular --> non-modular transition to preserve existing and documented use cases with such a prefix. Hm, I'm not convinced we need a core_ counterpart to module_param_named (that's nearly identical), when module_param_named already implements all of the above. Plenty of non-modular code already use it (e.g. workqueue, printk), and a prefix is automatically supplied (which can be overridden) in the non-modular case. That should already meet your requirements, no? Cc: Jessica Yu Cc: Rusty Russell Signed-off-by: Paul Gortmaker --- [Marking this RFC since I don't like the fact that it still requires non-modular code to use moduleparam.h -- one possible fix for that is to consider moving non-modular macros to a new param.h or similar. ] include/linux/moduleparam.h | 17 + 1 file changed, 17 insertions(+) diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 52666d90ca94..4f2b92345eb5 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -269,6 +269,23 @@ static inline void kernel_param_unlock(struct module *mod) __module_param_call("", name, _ops_##type, , perm, -1, 0) /** + * core_param_named - define a module compat core kernel parameter. + * @name: the name of the cmdline and sysfs parameter (often the same as var) + * @var: the variable + * @type: the type of the parameter + * @perm: visibility in sysfs + * + * core_param_named is just like module_param_named(), but cannot be modular + * and it _does_ add a prefix (such as "printk."). This is for compatibility + * with module_param_named(), and it exists to provide boot arg compatibility + * with code that was previously using the modular version with the prefix. + */ +#define core_param_named(name, var, type, perm) \ + param_check_##type(name, &(var)); \ + __module_param_call(KBUILD_MODNAME ".", name, _ops_##type,\ + , perm, -1, 0) + +/** * core_param_unsafe - same as core_param but taints kernel */ #define core_param_unsafe(name, var, type, perm)\ -- 2.10.1
Re: [PATCH v5 5/9] IB/isert: Replace semaphore sem with completion
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 6dd43f6..de80f56 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -619,7 +619,7 @@ mutex_unlock(_np->mutex); isert_info("np %p: Allow accept_np to continue\n", isert_np); - up(_np->sem); + complete(_np->comp); } static void @@ -2311,7 +2311,7 @@ struct rdma_cm_id * isert_err("Unable to allocate struct isert_np\n"); return -ENOMEM; } - sema_init(_np->sem, 0); + init_completion(_np->comp); This is still racy, a connect event can complete just before we init the completion and *will* get lost... This code started off with a waitqueue which exposes the same problem, see: 531b7bf4bd79 Target/iser: Fix iscsit_accept_np and rdma_cm racy flow So, still NAK from me...
Re: [PATCH v5 5/9] IB/isert: Replace semaphore sem with completion
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 6dd43f6..de80f56 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -619,7 +619,7 @@ mutex_unlock(_np->mutex); isert_info("np %p: Allow accept_np to continue\n", isert_np); - up(_np->sem); + complete(_np->comp); } static void @@ -2311,7 +2311,7 @@ struct rdma_cm_id * isert_err("Unable to allocate struct isert_np\n"); return -ENOMEM; } - sema_init(_np->sem, 0); + init_completion(_np->comp); This is still racy, a connect event can complete just before we init the completion and *will* get lost... This code started off with a waitqueue which exposes the same problem, see: 531b7bf4bd79 Target/iser: Fix iscsit_accept_np and rdma_cm racy flow So, still NAK from me...
Re: [PATCH 1/5] drm/modes: Rewrite the command line parser
Hi Sean, Thanks for taking the time to review this. On Wed, Nov 16, 2016 at 12:12:53PM -0500, Sean Paul wrote: > On Tue, Oct 18, 2016 at 4:29 AM, Maxime Ripard >wrote: > > Rewrite the command line parser in order to get away from the state machine > > parsing the video mode lines. > > > > Hopefully, this will allow to extend it more easily to support named modes > > and / or properties set directly on the command line. > > > > Signed-off-by: Maxime Ripard > > --- > > drivers/gpu/drm/drm_modes.c | 305 +++-- > > 1 file changed, 190 insertions(+), 115 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c > > index 53f07ac7c174..7d5bdca276f2 100644 > > --- a/drivers/gpu/drm/drm_modes.c > > +++ b/drivers/gpu/drm/drm_modes.c > > @@ -30,6 +30,7 @@ > > * authorization from the copyright holder(s) and author(s). > > */ > > > > +#include > > #include > > #include > > #include > > @@ -1261,6 +1262,131 @@ void drm_mode_connector_list_update(struct > > drm_connector *connector) > > } > > EXPORT_SYMBOL(drm_mode_connector_list_update); > > > > +static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr, > > + struct drm_cmdline_mode *mode) > > +{ > > + if (str[0] != '-') > > + return -EINVAL; > > + > > + mode->bpp = simple_strtol(str + 1, end_ptr, 10); > > + mode->bpp_specified = true; > > + > > + return 0; > > +} > > + > > +static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr, > > + struct drm_cmdline_mode *mode) > > +{ > > + if (str[0] != '@') > > + return -EINVAL; > > + > > + mode->refresh = simple_strtol(str + 1, end_ptr, 10); > > + mode->refresh_specified = true; > > + > > + return 0; > > +} > > + > > +static int drm_mode_parse_cmdline_extra(const char *str, int length, > > + struct drm_connector *connector, > > + struct drm_cmdline_mode *mode) > > +{ > > + int i; > > + > > + for (i = 0; i < length; i++) { > > + switch (str[i]) { > > + case 'i': > > + mode->interlace = true; > > + break; > > + case 'm': > > + mode->margins = true; > > + break; > > + case 'D': > > + if (mode->force != DRM_FORCE_UNSPECIFIED) > > + return -EINVAL; > > + > > + if ((connector->connector_type != > > DRM_MODE_CONNECTOR_DVII) && > > + (connector->connector_type != > > DRM_MODE_CONNECTOR_HDMIB)) > > + mode->force = DRM_FORCE_ON; > > + else > > + mode->force = DRM_FORCE_ON_DIGITAL; > > + break; > > + case 'd': > > + if (mode->force != DRM_FORCE_UNSPECIFIED) > > + return -EINVAL; > > + > > + mode->force = DRM_FORCE_OFF; > > + break; > > + case 'e': > > + if (mode->force != DRM_FORCE_UNSPECIFIED) > > + return -EINVAL; > > + > > + mode->force = DRM_FORCE_ON; > > + break; > > + default: > > + return -EINVAL; > > + } > > + } > > + > > + return 0; > > +} > > + > > +static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int > > length, > > + bool extras, > > + struct drm_connector *connector, > > + struct drm_cmdline_mode *mode) > > +{ > > + bool rb = false, cvt = false; > > + int xres = 0, yres = 0; > > + int remaining, i; > > + char *end_ptr; > > + > > + xres = simple_strtol(str, _ptr, 10); > > + > > checkpatch is telling me to use kstrtol instead, as simple_strtol is > deprecated > > > + if (end_ptr[0] != 'x') > > check that end_ptr != NULL? you should probably also check that xres > isn't an error (ie: -ERANGE or -EINVAL) > > > + return -EINVAL; > > + end_ptr++; > > + > > + yres = simple_strtol(end_ptr, _ptr, 10); > > check end_ptr != NULL and yres sane > > > + > > + remaining = length - (end_ptr - str); > > + if (remaining < 0) > > right, so if end_ptr is NULL here, we'll end up with a huge positive > value for remaining :) > > > + return -EINVAL; > > + > > + for (i = 0; i < remaining; i++) { > > + switch (end_ptr[i]) { > > + case 'M': >
Re: [PATCH 1/5] drm/modes: Rewrite the command line parser
Hi Sean, Thanks for taking the time to review this. On Wed, Nov 16, 2016 at 12:12:53PM -0500, Sean Paul wrote: > On Tue, Oct 18, 2016 at 4:29 AM, Maxime Ripard > wrote: > > Rewrite the command line parser in order to get away from the state machine > > parsing the video mode lines. > > > > Hopefully, this will allow to extend it more easily to support named modes > > and / or properties set directly on the command line. > > > > Signed-off-by: Maxime Ripard > > --- > > drivers/gpu/drm/drm_modes.c | 305 +++-- > > 1 file changed, 190 insertions(+), 115 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c > > index 53f07ac7c174..7d5bdca276f2 100644 > > --- a/drivers/gpu/drm/drm_modes.c > > +++ b/drivers/gpu/drm/drm_modes.c > > @@ -30,6 +30,7 @@ > > * authorization from the copyright holder(s) and author(s). > > */ > > > > +#include > > #include > > #include > > #include > > @@ -1261,6 +1262,131 @@ void drm_mode_connector_list_update(struct > > drm_connector *connector) > > } > > EXPORT_SYMBOL(drm_mode_connector_list_update); > > > > +static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr, > > + struct drm_cmdline_mode *mode) > > +{ > > + if (str[0] != '-') > > + return -EINVAL; > > + > > + mode->bpp = simple_strtol(str + 1, end_ptr, 10); > > + mode->bpp_specified = true; > > + > > + return 0; > > +} > > + > > +static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr, > > + struct drm_cmdline_mode *mode) > > +{ > > + if (str[0] != '@') > > + return -EINVAL; > > + > > + mode->refresh = simple_strtol(str + 1, end_ptr, 10); > > + mode->refresh_specified = true; > > + > > + return 0; > > +} > > + > > +static int drm_mode_parse_cmdline_extra(const char *str, int length, > > + struct drm_connector *connector, > > + struct drm_cmdline_mode *mode) > > +{ > > + int i; > > + > > + for (i = 0; i < length; i++) { > > + switch (str[i]) { > > + case 'i': > > + mode->interlace = true; > > + break; > > + case 'm': > > + mode->margins = true; > > + break; > > + case 'D': > > + if (mode->force != DRM_FORCE_UNSPECIFIED) > > + return -EINVAL; > > + > > + if ((connector->connector_type != > > DRM_MODE_CONNECTOR_DVII) && > > + (connector->connector_type != > > DRM_MODE_CONNECTOR_HDMIB)) > > + mode->force = DRM_FORCE_ON; > > + else > > + mode->force = DRM_FORCE_ON_DIGITAL; > > + break; > > + case 'd': > > + if (mode->force != DRM_FORCE_UNSPECIFIED) > > + return -EINVAL; > > + > > + mode->force = DRM_FORCE_OFF; > > + break; > > + case 'e': > > + if (mode->force != DRM_FORCE_UNSPECIFIED) > > + return -EINVAL; > > + > > + mode->force = DRM_FORCE_ON; > > + break; > > + default: > > + return -EINVAL; > > + } > > + } > > + > > + return 0; > > +} > > + > > +static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int > > length, > > + bool extras, > > + struct drm_connector *connector, > > + struct drm_cmdline_mode *mode) > > +{ > > + bool rb = false, cvt = false; > > + int xres = 0, yres = 0; > > + int remaining, i; > > + char *end_ptr; > > + > > + xres = simple_strtol(str, _ptr, 10); > > + > > checkpatch is telling me to use kstrtol instead, as simple_strtol is > deprecated > > > + if (end_ptr[0] != 'x') > > check that end_ptr != NULL? you should probably also check that xres > isn't an error (ie: -ERANGE or -EINVAL) > > > + return -EINVAL; > > + end_ptr++; > > + > > + yres = simple_strtol(end_ptr, _ptr, 10); > > check end_ptr != NULL and yres sane > > > + > > + remaining = length - (end_ptr - str); > > + if (remaining < 0) > > right, so if end_ptr is NULL here, we'll end up with a huge positive > value for remaining :) > > > + return -EINVAL; > > + > > + for (i = 0; i < remaining; i++) { > > + switch (end_ptr[i]) { > > + case 'M': > > + cvt = true; > > the previous code
Re: [PATCH] stm class: Add a missing call to put_device
Quentin Lambertwrites: > Most error branches following the call to class_find_device contain > a call to put_device. This patch add calls to put_device where > they are missing. > > This issue was found with Hector. > > Signed-off-by: Quentin Lambert > > --- > drivers/hwtracing/stm/core.c |4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > --- a/drivers/hwtracing/stm/core.c > +++ b/drivers/hwtracing/stm/core.c > @@ -368,8 +368,10 @@ static int stm_char_open(struct inode *i > return -ENODEV; > > stmf = kzalloc(sizeof(*stmf), GFP_KERNEL); > - if (!stmf) > + if (!stmf) { > + put_device(dev); > return -ENOMEM; > + } There is a goto label at the bottom of this function which is supposed to deal with this. See the fix that we already have [1] for this issue. [1] https://git.kernel.org/cgit/linux/kernel/git/ash/stm.git/commit/?h=stm-for-greg-20161118=a0ebf519b8a2666438d999c62995618c710573e5 Regards, -- alex
Re: [PATCH] stm class: Add a missing call to put_device
Quentin Lambert writes: > Most error branches following the call to class_find_device contain > a call to put_device. This patch add calls to put_device where > they are missing. > > This issue was found with Hector. > > Signed-off-by: Quentin Lambert > > --- > drivers/hwtracing/stm/core.c |4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > --- a/drivers/hwtracing/stm/core.c > +++ b/drivers/hwtracing/stm/core.c > @@ -368,8 +368,10 @@ static int stm_char_open(struct inode *i > return -ENODEV; > > stmf = kzalloc(sizeof(*stmf), GFP_KERNEL); > - if (!stmf) > + if (!stmf) { > + put_device(dev); > return -ENOMEM; > + } There is a goto label at the bottom of this function which is supposed to deal with this. See the fix that we already have [1] for this issue. [1] https://git.kernel.org/cgit/linux/kernel/git/ash/stm.git/commit/?h=stm-for-greg-20161118=a0ebf519b8a2666438d999c62995618c710573e5 Regards, -- alex
Re: [PATCH v16 05/15] clocksource/drivers/arm_arch_timer: fix a bug in arch_timer_register about arch_timer_uses_ppi
Hi Mark, On 19 November 2016 at 02:52, Mark Rutlandwrote: > On Wed, Nov 16, 2016 at 09:48:58PM +0800, fu@linaro.org wrote: >> From: Fu Wei >> >> The patch fix a potential bug about arch_timer_uses_ppi in >> arch_timer_register. >> On ARM64, we don't use ARCH_TIMER_PHYS_SECURE_PPI in Linux, so we will >> just igorne it in init code. > > That's not currently the case. I assume you mean we will in later > patches? If so, please make that clear in the commit message. > >> If arch_timer_uses_ppi is ARCH_TIMER_PHYS_NONSECURE_PPI, the orignal >> code of arch_timer_uses_ppi may go wrong. > > How? What specifically happens? > > We don't currently assign ARCH_TIMER_PHYS_NONSECURE_PPI to > arch_timer_uses_ppi, so I assume a later patch changes this. This change > should be folded into said patch; it doesn't make sense in isolation. yes, this patch is a preparation for the next which may set arch_timer_use_ppi as ARCH_TIMER_PHYS_NONSECURE_PPI. So you are right, I will merge this into the next and mention this change in the commit message. Great thanks > > Thanks, > Mark. > >> Signed-off-by: Fu Wei >> --- >> drivers/clocksource/arm_arch_timer.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/clocksource/arm_arch_timer.c >> b/drivers/clocksource/arm_arch_timer.c >> index dd1040d..6de164f 100644 >> --- a/drivers/clocksource/arm_arch_timer.c >> +++ b/drivers/clocksource/arm_arch_timer.c >> @@ -699,7 +699,7 @@ static int __init arch_timer_register(void) >> case ARCH_TIMER_PHYS_NONSECURE_PPI: >> err = request_percpu_irq(ppi, arch_timer_handler_phys, >>"arch_timer", arch_timer_evt); >> - if (!err && arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]) { >> + if (!err && arch_timer_has_nonsecure_ppi()) { >> ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]; >> err = request_percpu_irq(ppi, arch_timer_handler_phys, >>"arch_timer", arch_timer_evt); >> -- >> 2.7.4 >> -- Best regards, Fu Wei Software Engineer Red Hat
Re: [PATCH v16 05/15] clocksource/drivers/arm_arch_timer: fix a bug in arch_timer_register about arch_timer_uses_ppi
Hi Mark, On 19 November 2016 at 02:52, Mark Rutland wrote: > On Wed, Nov 16, 2016 at 09:48:58PM +0800, fu@linaro.org wrote: >> From: Fu Wei >> >> The patch fix a potential bug about arch_timer_uses_ppi in >> arch_timer_register. >> On ARM64, we don't use ARCH_TIMER_PHYS_SECURE_PPI in Linux, so we will >> just igorne it in init code. > > That's not currently the case. I assume you mean we will in later > patches? If so, please make that clear in the commit message. > >> If arch_timer_uses_ppi is ARCH_TIMER_PHYS_NONSECURE_PPI, the orignal >> code of arch_timer_uses_ppi may go wrong. > > How? What specifically happens? > > We don't currently assign ARCH_TIMER_PHYS_NONSECURE_PPI to > arch_timer_uses_ppi, so I assume a later patch changes this. This change > should be folded into said patch; it doesn't make sense in isolation. yes, this patch is a preparation for the next which may set arch_timer_use_ppi as ARCH_TIMER_PHYS_NONSECURE_PPI. So you are right, I will merge this into the next and mention this change in the commit message. Great thanks > > Thanks, > Mark. > >> Signed-off-by: Fu Wei >> --- >> drivers/clocksource/arm_arch_timer.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/clocksource/arm_arch_timer.c >> b/drivers/clocksource/arm_arch_timer.c >> index dd1040d..6de164f 100644 >> --- a/drivers/clocksource/arm_arch_timer.c >> +++ b/drivers/clocksource/arm_arch_timer.c >> @@ -699,7 +699,7 @@ static int __init arch_timer_register(void) >> case ARCH_TIMER_PHYS_NONSECURE_PPI: >> err = request_percpu_irq(ppi, arch_timer_handler_phys, >>"arch_timer", arch_timer_evt); >> - if (!err && arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]) { >> + if (!err && arch_timer_has_nonsecure_ppi()) { >> ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]; >> err = request_percpu_irq(ppi, arch_timer_handler_phys, >>"arch_timer", arch_timer_evt); >> -- >> 2.7.4 >> -- Best regards, Fu Wei Software Engineer Red Hat
Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles
On Fri, Nov 11, 2016 at 10:17:55AM +0100, Daniel Vetter wrote: > On Thu, Nov 10, 2016 at 03:56:30PM +0100, Maxime Ripard wrote: > > Hi Daniel, > > > > On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote: > > > On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote: > > > > Create overscan profiles reducing the displayed zone. > > > > > > > > For each TV standard (PAL and NTSC so far), we create 4 more reduced > > > > modes > > > > by steps of 5% that the user will be able to select. > > > > > > > > Signed-off-by: Maxime Ripard> > > > > > tbh I think if we agree to do this (and that still seems an open question) > > > I think there should be a generic helper to add these overscan modes with > > > increased porches. Anything that only depends upon the sink (and > > > overscanning is something the sink does) should imo be put into a suitable > > > helper library for everyone to share. > > > > > > Or maybe even stash it into the probe helpers and call it for all TV > > > connectors. Definitely not a driver-private thing. > > > > Last time we discussed it, my recollection was that you didn't want to > > have generic code for it, but I'd be happy to implement it. > > > > I'll come up with something like that. > > Well I can flip-flop around with the nonsense I'm sometimes emitting ;-) > Since you called me out, feel free to do whatever you want ... I also found the generic solution to be a much better solution, so I'll definitely implement it :) Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
Re: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles
On Fri, Nov 11, 2016 at 10:17:55AM +0100, Daniel Vetter wrote: > On Thu, Nov 10, 2016 at 03:56:30PM +0100, Maxime Ripard wrote: > > Hi Daniel, > > > > On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote: > > > On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote: > > > > Create overscan profiles reducing the displayed zone. > > > > > > > > For each TV standard (PAL and NTSC so far), we create 4 more reduced > > > > modes > > > > by steps of 5% that the user will be able to select. > > > > > > > > Signed-off-by: Maxime Ripard > > > > > > tbh I think if we agree to do this (and that still seems an open question) > > > I think there should be a generic helper to add these overscan modes with > > > increased porches. Anything that only depends upon the sink (and > > > overscanning is something the sink does) should imo be put into a suitable > > > helper library for everyone to share. > > > > > > Or maybe even stash it into the probe helpers and call it for all TV > > > connectors. Definitely not a driver-private thing. > > > > Last time we discussed it, my recollection was that you didn't want to > > have generic code for it, but I'd be happy to implement it. > > > > I'll come up with something like that. > > Well I can flip-flop around with the nonsense I'm sometimes emitting ;-) > Since you called me out, feel free to do whatever you want ... I also found the generic solution to be a much better solution, so I'll definitely implement it :) Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
Re: [PATCH resend] kbuild: provide include/asm/asm-prototypes.h for x86
Hi Adam, Thanks. I'd suggest doing x86: or x86/kbuild: prefix for the patch. Also possibly consider describing what the patch does at a higher level in your subject line, e.g.: x86/kbuild: enable modversions for symbols exported from asm Also, it wouldn't hurt to add a little changelog of your own. Describe problem then solution, e.g., Commit 4efca4ed ("kbuild: modversions for EXPORT_SYMBOL() for asm") adds modversion support for symbols exported from asm files. Architectures must include C-style declarations for those symbols in asm/asm-prototypes.h in order for them to be versioned. Add these declarations for x86, and an architecture-independent file that can be used for common symbols. (if you want to use that as-is or rewrite it, no problem). You can add Acked-by: Nicholas PigginAlso it's not a big deal, but if you redo the patch, you could consider splitting it into two (first add the generic header, then the x86 header), but both can go via the x86 tree. Thanks, Nick On Mon, 21 Nov 2016 07:39:45 +0100 Adam Borowski wrote: > Nicholas Piggin wrote: > > Architectures will need to have an include/asm/asm-prototypes.h that > > defines or #include<>s C-style prototypes for exported asm functions. > > We can do an asm-generic version for the common ones like memset so > > there's not a lot of pointless duplication there. > > Signed-off-by: Adam Borowski > Tested-by: Kalle Valo > --- > arch/x86/include/asm/asm-prototypes.h | 12 > include/asm-generic/asm-prototypes.h | 7 +++ > 2 files changed, 19 insertions(+) > create mode 100644 arch/x86/include/asm/asm-prototypes.h > create mode 100644 include/asm-generic/asm-prototypes.h > > diff --git a/arch/x86/include/asm/asm-prototypes.h > b/arch/x86/include/asm/asm-prototypes.h > new file mode 100644 > index 000..ae87224 > --- /dev/null > +++ b/arch/x86/include/asm/asm-prototypes.h > @@ -0,0 +1,12 @@ > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include > +#include > +#include > +#include > diff --git a/include/asm-generic/asm-prototypes.h > b/include/asm-generic/asm-prototypes.h > new file mode 100644 > index 000..df13637 > --- /dev/null > +++ b/include/asm-generic/asm-prototypes.h > @@ -0,0 +1,7 @@ > +#include > +extern void *__memset(void *, int, __kernel_size_t); > +extern void *__memcpy(void *, const void *, __kernel_size_t); > +extern void *__memmove(void *, const void *, __kernel_size_t); > +extern void *memset(void *, int, __kernel_size_t); > +extern void *memcpy(void *, const void *, __kernel_size_t); > +extern void *memmove(void *, const void *, __kernel_size_t);
Re: What exactly do 32-bit x86 exceptions push on the stack in the CS slot?
* Andy Lutomirskiwrote: > On Sat, Nov 19, 2016 at 6:11 PM, Brian Gerst wrote: > > On Sat, Nov 19, 2016 at 8:52 PM, Andy Lutomirski wrote: > >> This is a question for the old-timers here, since I can't find > >> anything resembling an answer in the SDM. > >> > >> Suppose an exception happens (#UD in this case, but I assume it > >> doesn't really matter). We're not in long mode, and the IDT is set up > >> to deliver to a normal 32-bit kernel code segment. We're running in > >> that very same code segment when the exception hits, so no CPL change > >> occurs and the TSS doesn't particularly matter. > >> > >> The CPU will push EFLAGS, CS, and RIP. Here's the question: what > >> happens to the high word of CS on the stack? > >> > >> The SDM appears to say nothing at all about this. Modern systems > >> (e.g. my laptop running in 32-bit legacy mode under KVM) appear to > >> zero-extend CS. But Matthew's 486DX appears to put garbage in the > >> high bits (or maybe just leave whatever was already on the stack in > >> place). > >> > >> Do any of you happen to know what's going on and when the behavior > >> changed? I'd like to know just how big of a problem this is. Because > >> if lots of CPUs work like Matthew's, we have lots of subtle bugs on > >> them. > >> > >> --Andy > > > > This came up a while back, and we was determined that we can't assume > > zero-extension in 32-bit mode because older processors only do a > > 16-bit write even on a 32-bit push. So all segments have to be > > treated as 16-bit values, or we have to explicitly zero-extend them. > > > > All 64-bit capable processors do zero-extend segments, even in 32-bit mode. > > This almost makes me want to change the definition of pt_regs on > 32-bit rather than fixing all the entry code. So I have applied your fix that addresses the worst fallout directly: fc0e81b2bea0 x86/traps: Ignore high word of regs->cs in early_fixup_exception() ... but otherwise we might be better off zeroing out the high bits of segment registers stored on the stack, in all entry code pathways - maybe using a single function and conditional on
Re: [PATCH resend] kbuild: provide include/asm/asm-prototypes.h for x86
Hi Adam, Thanks. I'd suggest doing x86: or x86/kbuild: prefix for the patch. Also possibly consider describing what the patch does at a higher level in your subject line, e.g.: x86/kbuild: enable modversions for symbols exported from asm Also, it wouldn't hurt to add a little changelog of your own. Describe problem then solution, e.g., Commit 4efca4ed ("kbuild: modversions for EXPORT_SYMBOL() for asm") adds modversion support for symbols exported from asm files. Architectures must include C-style declarations for those symbols in asm/asm-prototypes.h in order for them to be versioned. Add these declarations for x86, and an architecture-independent file that can be used for common symbols. (if you want to use that as-is or rewrite it, no problem). You can add Acked-by: Nicholas Piggin Also it's not a big deal, but if you redo the patch, you could consider splitting it into two (first add the generic header, then the x86 header), but both can go via the x86 tree. Thanks, Nick On Mon, 21 Nov 2016 07:39:45 +0100 Adam Borowski wrote: > Nicholas Piggin wrote: > > Architectures will need to have an include/asm/asm-prototypes.h that > > defines or #include<>s C-style prototypes for exported asm functions. > > We can do an asm-generic version for the common ones like memset so > > there's not a lot of pointless duplication there. > > Signed-off-by: Adam Borowski > Tested-by: Kalle Valo > --- > arch/x86/include/asm/asm-prototypes.h | 12 > include/asm-generic/asm-prototypes.h | 7 +++ > 2 files changed, 19 insertions(+) > create mode 100644 arch/x86/include/asm/asm-prototypes.h > create mode 100644 include/asm-generic/asm-prototypes.h > > diff --git a/arch/x86/include/asm/asm-prototypes.h > b/arch/x86/include/asm/asm-prototypes.h > new file mode 100644 > index 000..ae87224 > --- /dev/null > +++ b/arch/x86/include/asm/asm-prototypes.h > @@ -0,0 +1,12 @@ > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include > +#include > +#include > +#include > diff --git a/include/asm-generic/asm-prototypes.h > b/include/asm-generic/asm-prototypes.h > new file mode 100644 > index 000..df13637 > --- /dev/null > +++ b/include/asm-generic/asm-prototypes.h > @@ -0,0 +1,7 @@ > +#include > +extern void *__memset(void *, int, __kernel_size_t); > +extern void *__memcpy(void *, const void *, __kernel_size_t); > +extern void *__memmove(void *, const void *, __kernel_size_t); > +extern void *memset(void *, int, __kernel_size_t); > +extern void *memcpy(void *, const void *, __kernel_size_t); > +extern void *memmove(void *, const void *, __kernel_size_t);
Re: What exactly do 32-bit x86 exceptions push on the stack in the CS slot?
* Andy Lutomirski wrote: > On Sat, Nov 19, 2016 at 6:11 PM, Brian Gerst wrote: > > On Sat, Nov 19, 2016 at 8:52 PM, Andy Lutomirski wrote: > >> This is a question for the old-timers here, since I can't find > >> anything resembling an answer in the SDM. > >> > >> Suppose an exception happens (#UD in this case, but I assume it > >> doesn't really matter). We're not in long mode, and the IDT is set up > >> to deliver to a normal 32-bit kernel code segment. We're running in > >> that very same code segment when the exception hits, so no CPL change > >> occurs and the TSS doesn't particularly matter. > >> > >> The CPU will push EFLAGS, CS, and RIP. Here's the question: what > >> happens to the high word of CS on the stack? > >> > >> The SDM appears to say nothing at all about this. Modern systems > >> (e.g. my laptop running in 32-bit legacy mode under KVM) appear to > >> zero-extend CS. But Matthew's 486DX appears to put garbage in the > >> high bits (or maybe just leave whatever was already on the stack in > >> place). > >> > >> Do any of you happen to know what's going on and when the behavior > >> changed? I'd like to know just how big of a problem this is. Because > >> if lots of CPUs work like Matthew's, we have lots of subtle bugs on > >> them. > >> > >> --Andy > > > > This came up a while back, and we was determined that we can't assume > > zero-extension in 32-bit mode because older processors only do a > > 16-bit write even on a 32-bit push. So all segments have to be > > treated as 16-bit values, or we have to explicitly zero-extend them. > > > > All 64-bit capable processors do zero-extend segments, even in 32-bit mode. > > This almost makes me want to change the definition of pt_regs on > 32-bit rather than fixing all the entry code. So I have applied your fix that addresses the worst fallout directly: fc0e81b2bea0 x86/traps: Ignore high word of regs->cs in early_fixup_exception() ... but otherwise we might be better off zeroing out the high bits of segment registers stored on the stack, in all entry code pathways - maybe using a single function and conditional on
Re: [PATCH v3 0/2] Ajust lockdep static allocations for sparc
* Peter Zijlstrawrote: > On Fri, Nov 18, 2016 at 02:34:07PM -0500, David Miller wrote: > > From: Babu Moger > > Date: Tue, 27 Sep 2016 12:33:26 -0700 > > > > > These patches limit the static allocations for lockdep data structures > > > used for debugging locking correctness. For sparc, all the kernel's code, > > > data, and bss, must have locked translations in the TLB so that we don't > > > get TLB misses on kernel code and data. Current sparc chips have 8 TLB > > > entries available that may be locked down, and with a 4mb page size, > > > this gives a maximum of 32MB. With PROVE_LOCKING we could go over this > > > limit and cause system boot-up problems. These patches limit the static > > > allocations so that everything fits in current required size limit. > > > > > > patch 1 : Adds new config parameter CONFIG_PROVE_LOCKING_SMALL > > > Patch 2 : Adjusts the sizes based on the new config parameter > > > > > > v2-> v3: > > >Some more comments from Sam Ravnborg and Peter Zijlstra. > > >Defined PROVE_LOCKING_SMALL as invisible and moved the selection to > > >arch/sparc/Kconfig. > > > > > > v1-> v2: > > >As suggested by Peter Zijlstra, keeping the default as is. > > >Introduced new config variable CONFIG_PROVE_LOCKING_SMALL > > >to handle sparc specific case. > > > > > > v0: > > >Initial revision. > > > > Series applied, thanks. > > Heh, I was only waiting for an ACK from you, but this works too :-) Works for me too - as usual davem is fantastic in terms of efficient patch flow :) Thanks, Ingo
Re: [PATCH v3 0/2] Ajust lockdep static allocations for sparc
* Peter Zijlstra wrote: > On Fri, Nov 18, 2016 at 02:34:07PM -0500, David Miller wrote: > > From: Babu Moger > > Date: Tue, 27 Sep 2016 12:33:26 -0700 > > > > > These patches limit the static allocations for lockdep data structures > > > used for debugging locking correctness. For sparc, all the kernel's code, > > > data, and bss, must have locked translations in the TLB so that we don't > > > get TLB misses on kernel code and data. Current sparc chips have 8 TLB > > > entries available that may be locked down, and with a 4mb page size, > > > this gives a maximum of 32MB. With PROVE_LOCKING we could go over this > > > limit and cause system boot-up problems. These patches limit the static > > > allocations so that everything fits in current required size limit. > > > > > > patch 1 : Adds new config parameter CONFIG_PROVE_LOCKING_SMALL > > > Patch 2 : Adjusts the sizes based on the new config parameter > > > > > > v2-> v3: > > >Some more comments from Sam Ravnborg and Peter Zijlstra. > > >Defined PROVE_LOCKING_SMALL as invisible and moved the selection to > > >arch/sparc/Kconfig. > > > > > > v1-> v2: > > >As suggested by Peter Zijlstra, keeping the default as is. > > >Introduced new config variable CONFIG_PROVE_LOCKING_SMALL > > >to handle sparc specific case. > > > > > > v0: > > >Initial revision. > > > > Series applied, thanks. > > Heh, I was only waiting for an ACK from you, but this works too :-) Works for me too - as usual davem is fantastic in terms of efficient patch flow :) Thanks, Ingo
Re: [PATCH] drivers/usb: use READ_ONCE instead of deprecated ACCESS_ONCE
On Sun, Nov 20, 2016 at 08:09:40AM -0800, Davidlohr Bueso wrote: > Hi Greg! > > On Sun, 20 Nov 2016, Greg KH wrote: > > > On Sat, Nov 19, 2016 at 11:54:25AM -0800, Davidlohr Bueso wrote: > > > With the new standardized functions, we can replace all ACCESS_ONCE() > > > calls across relevant drivers/usb/. > > > > > > ACCESS_ONCE() does not work reliably on non-scalar types. For example > > > gcc 4.6 and 4.7 might remove the volatile tag for such accesses during > > > the SRA (scalar replacement of aggregates) step: > > > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 > > > > > > Update the new calls regardless of if it is a scalar type, this is > > > cleaner than having three alternatives. > > > > > > Signed-off-by: Davidlohr Bueso> > > > Nit, this doesn't match your From: line :( > > That's on purpose, and all my patches are the same. So they are all incorrect? Not good, why? You know this means I can't take them... > > If this is the case, why not just replacing the define for ACCESS_ONCE() > > with READ_ONCE() and then go back and just do a search/replace for the > > whole kernel all at once? > > So that we don't have three variants; the idea is to eventually > get rid of ACCESS_ONCE entirely. Then just get rid of it all at once. thanks, greg k-h
Re: [PATCH] drivers/usb: use READ_ONCE instead of deprecated ACCESS_ONCE
On Sun, Nov 20, 2016 at 08:09:40AM -0800, Davidlohr Bueso wrote: > Hi Greg! > > On Sun, 20 Nov 2016, Greg KH wrote: > > > On Sat, Nov 19, 2016 at 11:54:25AM -0800, Davidlohr Bueso wrote: > > > With the new standardized functions, we can replace all ACCESS_ONCE() > > > calls across relevant drivers/usb/. > > > > > > ACCESS_ONCE() does not work reliably on non-scalar types. For example > > > gcc 4.6 and 4.7 might remove the volatile tag for such accesses during > > > the SRA (scalar replacement of aggregates) step: > > > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 > > > > > > Update the new calls regardless of if it is a scalar type, this is > > > cleaner than having three alternatives. > > > > > > Signed-off-by: Davidlohr Bueso > > > > Nit, this doesn't match your From: line :( > > That's on purpose, and all my patches are the same. So they are all incorrect? Not good, why? You know this means I can't take them... > > If this is the case, why not just replacing the define for ACCESS_ONCE() > > with READ_ONCE() and then go back and just do a search/replace for the > > whole kernel all at once? > > So that we don't have three variants; the idea is to eventually > get rid of ACCESS_ONCE entirely. Then just get rid of it all at once. thanks, greg k-h
Re: [PATCH] thermal/powerclamp: add back module device table
On Mon, Nov 21, 2016 at 11:43:10AM +0800, Zhang Rui wrote: > On Thu, 2016-11-17 at 11:42 -0800, Jacob Pan wrote: > > On Tue, 15 Nov 2016 08:03:32 +0100 > > Greg Kroah-Hartmanwrote: > > > > > > > > On Mon, Nov 14, 2016 at 11:08:45AM -0800, Jacob Pan wrote: > > > > > > > > Commit 3105f234e0aba43e44e277c20f9b32ee8add43d4 replaced module > > > > cpu id table with a cpu feature check, which is logically > > > > correct. > > > > But we need the module device table to allow module auto loading. > > > > > > > > Fixes:3105f234 thermal/powerclamp: correct cpu support check > > > > Signed-off-by: Jacob Pan > > > > --- > > > > drivers/thermal/intel_powerclamp.c | 9 - > > > > 1 file changed, 8 insertions(+), 1 deletion(-) > > > > > > > > > This is not the correct way to submit patches for inclusion in the > > > stable kernel tree. Please read > > > Documentation/stable_kernel_rules.txt > > > for how to do this properly. > > > > > > > > Good to know, thanks. Rui will take care of it this time. Per Rui > > "I will apply patch 1 and queue up for next -rc and 4.8 stable." > > > > Just find another problem. > We're still missing this upstream > commit 3105f234e0aba43e44e277c20f9b32ee8add43d4 (thermal/powerclamp: > correct cpu support check) for 4.7 stable, and in this case, we can not > queue this patch for both 4.7 and 4.8 stable at the moment because it > does not apply to 4.7 stable. I don't understand, 4.7 is end-of-life, no one cares about it anymore, why are you worrying about that kernel version? confused, greg k-h
Re: [PATCH] thermal/powerclamp: add back module device table
On Mon, Nov 21, 2016 at 11:43:10AM +0800, Zhang Rui wrote: > On Thu, 2016-11-17 at 11:42 -0800, Jacob Pan wrote: > > On Tue, 15 Nov 2016 08:03:32 +0100 > > Greg Kroah-Hartman wrote: > > > > > > > > On Mon, Nov 14, 2016 at 11:08:45AM -0800, Jacob Pan wrote: > > > > > > > > Commit 3105f234e0aba43e44e277c20f9b32ee8add43d4 replaced module > > > > cpu id table with a cpu feature check, which is logically > > > > correct. > > > > But we need the module device table to allow module auto loading. > > > > > > > > Fixes:3105f234 thermal/powerclamp: correct cpu support check > > > > Signed-off-by: Jacob Pan > > > > --- > > > > drivers/thermal/intel_powerclamp.c | 9 - > > > > 1 file changed, 8 insertions(+), 1 deletion(-) > > > > > > > > > This is not the correct way to submit patches for inclusion in the > > > stable kernel tree. Please read > > > Documentation/stable_kernel_rules.txt > > > for how to do this properly. > > > > > > > > Good to know, thanks. Rui will take care of it this time. Per Rui > > "I will apply patch 1 and queue up for next -rc and 4.8 stable." > > > > Just find another problem. > We're still missing this upstream > commit 3105f234e0aba43e44e277c20f9b32ee8add43d4 (thermal/powerclamp: > correct cpu support check) for 4.7 stable, and in this case, we can not > queue this patch for both 4.7 and 4.8 stable at the moment because it > does not apply to 4.7 stable. I don't understand, 4.7 is end-of-life, no one cares about it anymore, why are you worrying about that kernel version? confused, greg k-h
[PATCH] ARM: dts: exynos: remove the cd-gpios property for eMMC of odroid-xu3/4
Odroid-xu3/4 didn't need to use the cd-gpios for detecting card. Because Host controller has the CDETECT register through SDx_CDN line. Host controller can know whether card is inserted or not with this register. When i have checked the Odroid-xu3/4, they are using CDETECT register. (Not using exteranl cd-gpio.) Fixes: fb1aeedb61ad ("ARM: dts: add mmc detect gpio for exynos5422-odroidxu3") Signed-off-by: Jaehoon Chung--- arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 9e63328..05b9afdd 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -510,7 +510,6 @@ _0 { status = "okay"; mmc-pwrseq = <_pwrseq>; - cd-gpios = < 2 GPIO_ACTIVE_LOW>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; -- 2.10.1
[PATCH] ARM: dts: exynos: remove the cd-gpios property for eMMC of odroid-xu3/4
Odroid-xu3/4 didn't need to use the cd-gpios for detecting card. Because Host controller has the CDETECT register through SDx_CDN line. Host controller can know whether card is inserted or not with this register. When i have checked the Odroid-xu3/4, they are using CDETECT register. (Not using exteranl cd-gpio.) Fixes: fb1aeedb61ad ("ARM: dts: add mmc detect gpio for exynos5422-odroidxu3") Signed-off-by: Jaehoon Chung --- arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 9e63328..05b9afdd 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -510,7 +510,6 @@ _0 { status = "okay"; mmc-pwrseq = <_pwrseq>; - cd-gpios = < 2 GPIO_ACTIVE_LOW>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; -- 2.10.1
Re: [PATCH 00/36] cputime: Convert core use of cputime_t to nsecs
On Fri, 18 Nov 2016 15:47:02 +0100 Frederic Weisbeckerwrote: > On Fri, Nov 18, 2016 at 01:08:46PM +0100, Martin Schwidefsky wrote: > > On Thu, 17 Nov 2016 19:08:07 +0100 > > Frederic Weisbecker wrote: > > > > > I'm sorry for the patchbomb, especially as I usually complain about > > > these myself but I don't see any way to split this patchset into > > > standalone pieces, none of which would make any sense... All I can do > > > is to isolate about 3 cleanup patches. > > > > On first glance the patches look ok-ish, but I am not happy about the > > direction this takes. > > > > I can understand the wish to consolidate the common code to a single > > format which is nano-seconds. It will have repercussions though. > > > > First the obvious problem, it does not compile for s390: > > > > arch/s390/kernel/vtime.c: In function 'do_account_vtime': > > arch/s390/kernel/vtime.c:140:25: error: implicit declaration of function > > 'cputime_to_nsecs' [-Werror=implicit-function-declaration] > > account_user_time(tsk, cputime_to_nsecs(user)); > > ^~~~ > > arch/s390/kernel/idle.c: In function 'enabled_wait': > > arch/s390/kernel/idle.c:46:20: error: implicit declaration of function > > 'cputime_to_nsecs' [-Werror=implicit-function-declaration] > > account_idle_time(cputime_to_nsecs(idle_time)); > > ^~~~ > > arch/s390/kernel/idle.c: In function 'arch_cpu_idle_time': > > arch/s390/kernel/idle.c:100:9: error: implicit declaration of function > > 'cputime_to_nsec' [-Werror=implicit-function-declaration] > > return cputime_to_nsec(idle_enter ? ((idle_exit ?: now) - idle_enter) : > > 0); > > ^~~ > > Yes sorry I haven't yet done much build-testing. I should have written that > it's > not build-tested yet. This patchset in its current state is rather an RFC. No big deal, I got it to compile with a small change. > > The error at idle.c:100 is a typo cputime_to_nsec vs cputime_to_nsecs. > > The other two could probably be solved with an additional include but the > > default cputime_to_nsecs is in include/linux/cputime.h is this: > > > > #ifndef cputime_to_nsecs > > # define cputime_to_nsecs(__ct) \ > > (cputime_to_usecs(__ct) * NSEC_PER_USEC) > > #endif > > > > which downgrades the accuracy for s390 from better than nano-seconds > > to micro-seconds. Not good. For the s390 cputime format you would have > > to do > > > > static inline unsigned long long cputime_to_nsecs(const cputime_t cputime) > > { > > return ((__force unsigned long long) cputime * 1000) >> 12; > > } > > I agree, that loss of acurracy is my biggest worry. Hence the accumulation > idea, but more about that later. We can not allow that to happen, but the accumulation should take care of it. > > > > But this *example* function has an overflow problem. > > > > > So currently, cputime_t serves the purpose, for s390 and > > > powerpc (on CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y), to avoid converting > > > arch clock counters to nanosecs or jiffies while accounting cputime. > > > > The cputime_t has several purposes: > > 1) Allow for different units in the calculations for virtual cpu time. > >There are currently three models: jiffies, nano-seconds and the native > >TOD clock format for s390 which is a bit better than nano-seconds. > > Sure, I don't disagree with that, just with the way it is done (ie: stored > and maintained in the core to this very obscure type). > > > 2) Act as a marker in the common code where a virtual cpu time is used. > >This is more important than you might think, unfortunately it is very > >easy to confuse a wall-clock delta with cpu time. > > There you lost me, I don't get which confusion you're pointing. The confusion stems from the fact that you do *not* have a simple nano-second value but a modal value that depends on the architecture. More below.. > > 3) Avoid expensive operations on the fast path to convert the native cpu > >time to something else. Instead move the expensive calculation to the > >read-out code, e.g. fs/proc. > > > > You patches breaks all three of these purposes. My main gripe is with 3). > > > > > But this comes at the cost of a lot of complexity and uglification > > > in the core code to deal with such an opaque type that relies on lots of > > > mutators and accessors in order to deal with a random granularity time > > > unit that also involve lots of workarounds and likely some performance > > > penalties. > > > > Having an opaque type with a set of helper functions is the whole point, no? > > And I would not call the generic implementations for jiffies or nano-seconds > > complex, these are easy enough to understand. And what are the performance > > penalties you are talking about? > > Just because some code isn't too complex doesn't mean we really want to keep > it. > I get regular questions about what
Re: [PATCH 00/36] cputime: Convert core use of cputime_t to nsecs
On Fri, 18 Nov 2016 15:47:02 +0100 Frederic Weisbecker wrote: > On Fri, Nov 18, 2016 at 01:08:46PM +0100, Martin Schwidefsky wrote: > > On Thu, 17 Nov 2016 19:08:07 +0100 > > Frederic Weisbecker wrote: > > > > > I'm sorry for the patchbomb, especially as I usually complain about > > > these myself but I don't see any way to split this patchset into > > > standalone pieces, none of which would make any sense... All I can do > > > is to isolate about 3 cleanup patches. > > > > On first glance the patches look ok-ish, but I am not happy about the > > direction this takes. > > > > I can understand the wish to consolidate the common code to a single > > format which is nano-seconds. It will have repercussions though. > > > > First the obvious problem, it does not compile for s390: > > > > arch/s390/kernel/vtime.c: In function 'do_account_vtime': > > arch/s390/kernel/vtime.c:140:25: error: implicit declaration of function > > 'cputime_to_nsecs' [-Werror=implicit-function-declaration] > > account_user_time(tsk, cputime_to_nsecs(user)); > > ^~~~ > > arch/s390/kernel/idle.c: In function 'enabled_wait': > > arch/s390/kernel/idle.c:46:20: error: implicit declaration of function > > 'cputime_to_nsecs' [-Werror=implicit-function-declaration] > > account_idle_time(cputime_to_nsecs(idle_time)); > > ^~~~ > > arch/s390/kernel/idle.c: In function 'arch_cpu_idle_time': > > arch/s390/kernel/idle.c:100:9: error: implicit declaration of function > > 'cputime_to_nsec' [-Werror=implicit-function-declaration] > > return cputime_to_nsec(idle_enter ? ((idle_exit ?: now) - idle_enter) : > > 0); > > ^~~ > > Yes sorry I haven't yet done much build-testing. I should have written that > it's > not build-tested yet. This patchset in its current state is rather an RFC. No big deal, I got it to compile with a small change. > > The error at idle.c:100 is a typo cputime_to_nsec vs cputime_to_nsecs. > > The other two could probably be solved with an additional include but the > > default cputime_to_nsecs is in include/linux/cputime.h is this: > > > > #ifndef cputime_to_nsecs > > # define cputime_to_nsecs(__ct) \ > > (cputime_to_usecs(__ct) * NSEC_PER_USEC) > > #endif > > > > which downgrades the accuracy for s390 from better than nano-seconds > > to micro-seconds. Not good. For the s390 cputime format you would have > > to do > > > > static inline unsigned long long cputime_to_nsecs(const cputime_t cputime) > > { > > return ((__force unsigned long long) cputime * 1000) >> 12; > > } > > I agree, that loss of acurracy is my biggest worry. Hence the accumulation > idea, but more about that later. We can not allow that to happen, but the accumulation should take care of it. > > > > But this *example* function has an overflow problem. > > > > > So currently, cputime_t serves the purpose, for s390 and > > > powerpc (on CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y), to avoid converting > > > arch clock counters to nanosecs or jiffies while accounting cputime. > > > > The cputime_t has several purposes: > > 1) Allow for different units in the calculations for virtual cpu time. > >There are currently three models: jiffies, nano-seconds and the native > >TOD clock format for s390 which is a bit better than nano-seconds. > > Sure, I don't disagree with that, just with the way it is done (ie: stored > and maintained in the core to this very obscure type). > > > 2) Act as a marker in the common code where a virtual cpu time is used. > >This is more important than you might think, unfortunately it is very > >easy to confuse a wall-clock delta with cpu time. > > There you lost me, I don't get which confusion you're pointing. The confusion stems from the fact that you do *not* have a simple nano-second value but a modal value that depends on the architecture. More below.. > > 3) Avoid expensive operations on the fast path to convert the native cpu > >time to something else. Instead move the expensive calculation to the > >read-out code, e.g. fs/proc. > > > > You patches breaks all three of these purposes. My main gripe is with 3). > > > > > But this comes at the cost of a lot of complexity and uglification > > > in the core code to deal with such an opaque type that relies on lots of > > > mutators and accessors in order to deal with a random granularity time > > > unit that also involve lots of workarounds and likely some performance > > > penalties. > > > > Having an opaque type with a set of helper functions is the whole point, no? > > And I would not call the generic implementations for jiffies or nano-seconds > > complex, these are easy enough to understand. And what are the performance > > penalties you are talking about? > > Just because some code isn't too complex doesn't mean we really want to keep > it. > I get regular questions about what unit does cputime_t map to on a given >
Re: [HMM v13 01/18] mm/memory/hotplug: convert device parameter bool to set of flags
On 11/21/2016 10:23 AM, Jerome Glisse wrote: > On Mon, Nov 21, 2016 at 11:44:36AM +1100, Balbir Singh wrote: >> >> >> On 19/11/16 05:18, Jérôme Glisse wrote: >>> Only usefull for arch where we support ZONE_DEVICE and where we want to >>> also support un-addressable device memory. We need struct page for such >>> un-addressable memory. But we should avoid populating the kernel linear >>> mapping for the physical address range because there is no real memory >>> or anything behind those physical address. >>> >>> Hence we need more flags than just knowing if it is device memory or not. >>> >> >> >> Isn't it better to add a wrapper to arch_add/remove_memory and do those >> checks inside and then call arch_add/remove_memory to reduce the churn. >> If you need selectively enable MEMORY_UNADDRESSABLE that can be done with >> _ARCH_HAS_FEATURE > > The flag parameter can be use by other new features and thus i thought the > churn was fine. But i do not mind either way, whatever people like best. Right, once we get the device memory classification right, these flags can be used in more places. > > [...] > >>> -extern int arch_add_memory(int nid, u64 start, u64 size, bool for_device); >>> + >>> +/* >>> + * For device memory we want more informations than just knowing it is >>> device >> information >>> + * memory. We want to know if we can migrate it (ie it is not storage >>> memory >>> + * use by DAX). Is it addressable by the CPU ? Some device memory like GPU >>> + * memory can not be access by CPU but we still want struct page so that we >> accessed >>> + * can use it like regular memory. >> >> Can you please add some details on why -- migration needs them for example? > > I am not sure what you mean ? DAX ie persistent memory device is intended to > be > use for filesystem or persistent storage. Hence memory migration does not > apply > to it (it would go against its purpose). Why ? It can still be used for compaction, HW errors etc where we need to move between persistent storage areas. The source and destination can be persistent storage memory. > > So i want to extend ZONE_DEVICE to be more then just DAX/persistent memory. > For > that i need to differentatiate between device memory that can be migrated and > should be more or less treated like regular memory (with struct page). This is > what the MEMORY_MOVABLE flag is for. ZONE_DEVICE right now also supports struct page for the addressable memory, (whether inside it's own range or in system RAM) with this we are extending it to cover un-addressable memory with struct pages. Yes the differentiation is required. > > Finaly in my case the device memory is not accessible by the CPU so i need yet > another flag. In the end i am extending ZONE_DEVICE to be use for 3 differents > type of memory. > > Is this the kind of explanation you are looking for ?
Re: [HMM v13 01/18] mm/memory/hotplug: convert device parameter bool to set of flags
On 11/21/2016 10:23 AM, Jerome Glisse wrote: > On Mon, Nov 21, 2016 at 11:44:36AM +1100, Balbir Singh wrote: >> >> >> On 19/11/16 05:18, Jérôme Glisse wrote: >>> Only usefull for arch where we support ZONE_DEVICE and where we want to >>> also support un-addressable device memory. We need struct page for such >>> un-addressable memory. But we should avoid populating the kernel linear >>> mapping for the physical address range because there is no real memory >>> or anything behind those physical address. >>> >>> Hence we need more flags than just knowing if it is device memory or not. >>> >> >> >> Isn't it better to add a wrapper to arch_add/remove_memory and do those >> checks inside and then call arch_add/remove_memory to reduce the churn. >> If you need selectively enable MEMORY_UNADDRESSABLE that can be done with >> _ARCH_HAS_FEATURE > > The flag parameter can be use by other new features and thus i thought the > churn was fine. But i do not mind either way, whatever people like best. Right, once we get the device memory classification right, these flags can be used in more places. > > [...] > >>> -extern int arch_add_memory(int nid, u64 start, u64 size, bool for_device); >>> + >>> +/* >>> + * For device memory we want more informations than just knowing it is >>> device >> information >>> + * memory. We want to know if we can migrate it (ie it is not storage >>> memory >>> + * use by DAX). Is it addressable by the CPU ? Some device memory like GPU >>> + * memory can not be access by CPU but we still want struct page so that we >> accessed >>> + * can use it like regular memory. >> >> Can you please add some details on why -- migration needs them for example? > > I am not sure what you mean ? DAX ie persistent memory device is intended to > be > use for filesystem or persistent storage. Hence memory migration does not > apply > to it (it would go against its purpose). Why ? It can still be used for compaction, HW errors etc where we need to move between persistent storage areas. The source and destination can be persistent storage memory. > > So i want to extend ZONE_DEVICE to be more then just DAX/persistent memory. > For > that i need to differentatiate between device memory that can be migrated and > should be more or less treated like regular memory (with struct page). This is > what the MEMORY_MOVABLE flag is for. ZONE_DEVICE right now also supports struct page for the addressable memory, (whether inside it's own range or in system RAM) with this we are extending it to cover un-addressable memory with struct pages. Yes the differentiation is required. > > Finaly in my case the device memory is not accessible by the CPU so i need yet > another flag. In the end i am extending ZONE_DEVICE to be use for 3 differents > type of memory. > > Is this the kind of explanation you are looking for ?
[lkp] [rcu] 83ee00c6cf: WARNING:at_kernel/softirq.c:#__local_bh_enable
FYI, we noticed the following commit: https://github.com/0day-ci/linux Ding-Tianhong/rcu-fix-the-OOM-problem-of-huge-IP-abnormal-packet-traffic/20161118-204521 commit 83ee00c6cf5eaa85f74094d6800732edf7114ef9 ("rcu: fix the OOM problem of huge IP abnormal packet traffic") in testcase: boot on test machine: qemu-system-x86_64 -enable-kvm -m 320M caused below changes: ++++ || 68ad1194cf | 83ee00c6cf | ++++ | boot_successes | 6 | 0 | | boot_failures | 0 | 6 | | WARNING:at_kernel/softirq.c:#__local_bh_enable | 0 | 6 | | calltrace:_local_bh_enable | 0 | 6 | ++++ [0.846125] PCI: CLS 0 bytes, default 64 [0.847479] Unpacking initramfs... [0.849690] [ cut here ] [0.850615] WARNING: CPU: 0 PID: 9 at kernel/softirq.c:140 __local_bh_enable+0x35/0x41 [0.852518] Modules linked in: [0.853178] CPU: 0 PID: 9 Comm: rcuos/0 Not tainted 4.9.0-rc1-00041-g83ee00c #1 [0.854630] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-20161025_171302-gandalf 04/01/2014 [0.856628] 882f7c70 81267760 81837340 [0.858185] 882f7cb0 81060e07 008c0009 0200 [0.859742] 882f7dc8 88000f808bb0 0001 88000f808bb0 [0.861293] Call Trace: [0.861795] [] dump_stack+0x61/0x7e [0.862809] [] __warn+0xf5/0x110 [0.863870] [] warn_slowpath_null+0x18/0x1a [0.865020] [] __local_bh_enable+0x35/0x41 [0.866143] [] _local_bh_enable+0x3d/0x3f [0.867252] [] rcu_nocb_kthread+0x69b/0x6f2 [0.868393] [] ? __d_free_external+0x3f/0x3f [0.869554] [] ? note_gp_changes+0xcd/0xcd [0.870679] [] ? __schedule+0x5fc/0x73c [0.871755] [] ? note_gp_changes+0xcd/0xcd [0.872980] [] kthread+0x191/0x1a0 [0.873971] [] ? kthread_park+0x5d/0x5d [0.875059] [] ? finish_task_switch+0x1e4/0x2a0 [0.876262] [] ? kthread_park+0x5d/0x5d [0.877331] [] ? kthread_park+0x5d/0x5d [0.878401] [] ret_from_fork+0x25/0x30 [0.879484] ---[ end trace 825c5dbf85ebfadd ]--- [0.899723] workqueue: round-robin CPU selection forced, expect performance impact [2.115863] Freeing initrd memory: 9088K (88001370 - 880013fe) To reproduce: git clone git://git.kernel.org/pub/scm/linux/kernel/git/wfg/lkp-tests.git cd lkp-tests bin/lkp qemu -k job-script # job-script is attached in this email Thanks, Xiaolong # # Automatically generated file; DO NOT EDIT. # Linux/x86_64 4.9.0-rc1 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y CONFIG_X86=y CONFIG_INSTRUCTION_DECODER=y CONFIG_OUTPUT_FORMAT="elf64-x86-64" CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_MMU=y CONFIG_ARCH_MMAP_RND_BITS_MIN=28 CONFIG_ARCH_MMAP_RND_BITS_MAX=32 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_ARCH_WANT_GENERAL_HUGETLB=y CONFIG_ZONE_DMA32=y CONFIG_AUDIT_ARCH=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_KASAN_SHADOW_OFFSET=0xdc00 CONFIG_X86_64_SMP=y CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_DEBUG_RODATA=y CONFIG_PGTABLE_LEVELS=4 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y CONFIG_THREAD_INFO_IN_TASK=y # # General setup # CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" # CONFIG_COMPILE_TEST is not set CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_XZ=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_HAVE_KERNEL_LZ4=y # CONFIG_KERNEL_GZIP is not set # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set # CONFIG_KERNEL_XZ is not set CONFIG_KERNEL_LZO=y # CONFIG_KERNEL_LZ4 is not set CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_FHANDLE=y CONFIG_USELIB=y #
[lkp] [rcu] 83ee00c6cf: WARNING:at_kernel/softirq.c:#__local_bh_enable
FYI, we noticed the following commit: https://github.com/0day-ci/linux Ding-Tianhong/rcu-fix-the-OOM-problem-of-huge-IP-abnormal-packet-traffic/20161118-204521 commit 83ee00c6cf5eaa85f74094d6800732edf7114ef9 ("rcu: fix the OOM problem of huge IP abnormal packet traffic") in testcase: boot on test machine: qemu-system-x86_64 -enable-kvm -m 320M caused below changes: ++++ || 68ad1194cf | 83ee00c6cf | ++++ | boot_successes | 6 | 0 | | boot_failures | 0 | 6 | | WARNING:at_kernel/softirq.c:#__local_bh_enable | 0 | 6 | | calltrace:_local_bh_enable | 0 | 6 | ++++ [0.846125] PCI: CLS 0 bytes, default 64 [0.847479] Unpacking initramfs... [0.849690] [ cut here ] [0.850615] WARNING: CPU: 0 PID: 9 at kernel/softirq.c:140 __local_bh_enable+0x35/0x41 [0.852518] Modules linked in: [0.853178] CPU: 0 PID: 9 Comm: rcuos/0 Not tainted 4.9.0-rc1-00041-g83ee00c #1 [0.854630] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-20161025_171302-gandalf 04/01/2014 [0.856628] 882f7c70 81267760 81837340 [0.858185] 882f7cb0 81060e07 008c0009 0200 [0.859742] 882f7dc8 88000f808bb0 0001 88000f808bb0 [0.861293] Call Trace: [0.861795] [] dump_stack+0x61/0x7e [0.862809] [] __warn+0xf5/0x110 [0.863870] [] warn_slowpath_null+0x18/0x1a [0.865020] [] __local_bh_enable+0x35/0x41 [0.866143] [] _local_bh_enable+0x3d/0x3f [0.867252] [] rcu_nocb_kthread+0x69b/0x6f2 [0.868393] [] ? __d_free_external+0x3f/0x3f [0.869554] [] ? note_gp_changes+0xcd/0xcd [0.870679] [] ? __schedule+0x5fc/0x73c [0.871755] [] ? note_gp_changes+0xcd/0xcd [0.872980] [] kthread+0x191/0x1a0 [0.873971] [] ? kthread_park+0x5d/0x5d [0.875059] [] ? finish_task_switch+0x1e4/0x2a0 [0.876262] [] ? kthread_park+0x5d/0x5d [0.877331] [] ? kthread_park+0x5d/0x5d [0.878401] [] ret_from_fork+0x25/0x30 [0.879484] ---[ end trace 825c5dbf85ebfadd ]--- [0.899723] workqueue: round-robin CPU selection forced, expect performance impact [2.115863] Freeing initrd memory: 9088K (88001370 - 880013fe) To reproduce: git clone git://git.kernel.org/pub/scm/linux/kernel/git/wfg/lkp-tests.git cd lkp-tests bin/lkp qemu -k job-script # job-script is attached in this email Thanks, Xiaolong # # Automatically generated file; DO NOT EDIT. # Linux/x86_64 4.9.0-rc1 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y CONFIG_X86=y CONFIG_INSTRUCTION_DECODER=y CONFIG_OUTPUT_FORMAT="elf64-x86-64" CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_MMU=y CONFIG_ARCH_MMAP_RND_BITS_MIN=28 CONFIG_ARCH_MMAP_RND_BITS_MAX=32 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_ARCH_WANT_GENERAL_HUGETLB=y CONFIG_ZONE_DMA32=y CONFIG_AUDIT_ARCH=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_KASAN_SHADOW_OFFSET=0xdc00 CONFIG_X86_64_SMP=y CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_DEBUG_RODATA=y CONFIG_PGTABLE_LEVELS=4 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y CONFIG_THREAD_INFO_IN_TASK=y # # General setup # CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" # CONFIG_COMPILE_TEST is not set CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_XZ=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_HAVE_KERNEL_LZ4=y # CONFIG_KERNEL_GZIP is not set # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set # CONFIG_KERNEL_XZ is not set CONFIG_KERNEL_LZO=y # CONFIG_KERNEL_LZ4 is not set CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_FHANDLE=y CONFIG_USELIB=y #
[PATCH] ACPI: small formatting fixes
A quick cleanup that passes scripts/checkpatch.pl -f . Signed-off-by: Nick Desaulniers--- arch/x86/kernel/acpi/cstate.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index af15f44..ed52aec 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2005 Intel Corporation - * Venkatesh Pallipadi - * - Added _PDC for SMP C-states on Intel CPUs + * Venkatesh Pallipadi + * - Added _PDC for SMP C-states on Intel CPUs */ #include @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -50,8 +49,8 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, * P4, Core and beyond CPUs */ if (c->x86_vendor == X86_VENDOR_INTEL && - (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f))) - flags->bm_control = 0; + (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f))) + flags->bm_control = 0; } EXPORT_SYMBOL(acpi_processor_power_init_bm_check); @@ -89,7 +88,8 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx) retval = 0; /* If the HW does not support any sub-states in this C-state */ if (num_cstate_subtype == 0) { - pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n", cx->address, edx_part); + pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n", + cx->address, edx_part); retval = -1; goto out; } @@ -103,9 +103,8 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx) if (!mwait_supported[cstate_type]) { mwait_supported[cstate_type] = 1; - printk(KERN_DEBUG - "Monitor-Mwait will be used to enter C-%d " - "state\n", cx->type); + pr_debug("Monitor-Mwait will be used to enter C-%d state\n", + cx->type); } snprintf(cx->desc, ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x", @@ -159,13 +158,14 @@ void __cpuidle acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu); mwait_idle_with_hints(percpu_entry->states[cx->index].eax, - percpu_entry->states[cx->index].ecx); + percpu_entry->states[cx->index].ecx); } EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_enter); static int __init ffh_cstate_init(void) { struct cpuinfo_x86 *c = _cpu_data; + if (c->x86_vendor != X86_VENDOR_INTEL) return -1; -- 2.9.3
[PATCH] ACPI: small formatting fixes
A quick cleanup that passes scripts/checkpatch.pl -f . Signed-off-by: Nick Desaulniers --- arch/x86/kernel/acpi/cstate.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index af15f44..ed52aec 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2005 Intel Corporation - * Venkatesh Pallipadi - * - Added _PDC for SMP C-states on Intel CPUs + * Venkatesh Pallipadi + * - Added _PDC for SMP C-states on Intel CPUs */ #include @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -50,8 +49,8 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, * P4, Core and beyond CPUs */ if (c->x86_vendor == X86_VENDOR_INTEL && - (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f))) - flags->bm_control = 0; + (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f))) + flags->bm_control = 0; } EXPORT_SYMBOL(acpi_processor_power_init_bm_check); @@ -89,7 +88,8 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx) retval = 0; /* If the HW does not support any sub-states in this C-state */ if (num_cstate_subtype == 0) { - pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n", cx->address, edx_part); + pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n", + cx->address, edx_part); retval = -1; goto out; } @@ -103,9 +103,8 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx) if (!mwait_supported[cstate_type]) { mwait_supported[cstate_type] = 1; - printk(KERN_DEBUG - "Monitor-Mwait will be used to enter C-%d " - "state\n", cx->type); + pr_debug("Monitor-Mwait will be used to enter C-%d state\n", + cx->type); } snprintf(cx->desc, ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x", @@ -159,13 +158,14 @@ void __cpuidle acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu); mwait_idle_with_hints(percpu_entry->states[cx->index].eax, - percpu_entry->states[cx->index].ecx); + percpu_entry->states[cx->index].ecx); } EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_enter); static int __init ffh_cstate_init(void) { struct cpuinfo_x86 *c = _cpu_data; + if (c->x86_vendor != X86_VENDOR_INTEL) return -1; -- 2.9.3
Re: [HMM v13 01/18] mm/memory/hotplug: convert device parameter bool to set of flags
On 11/18/2016 11:48 PM, Jérôme Glisse wrote: > Only usefull for arch where we support ZONE_DEVICE and where we want to A small nit s/usefull/useful/ > also support un-addressable device memory. We need struct page for such > un-addressable memory. But we should avoid populating the kernel linear > mapping for the physical address range because there is no real memory > or anything behind those physical address. > > Hence we need more flags than just knowing if it is device memory or not. > > Signed-off-by: Jérôme Glisse> Cc: Russell King > Cc: Benjamin Herrenschmidt > Cc: Paul Mackerras > Cc: Michael Ellerman > Cc: Martin Schwidefsky > Cc: Heiko Carstens > Cc: Yoshinori Sato > Cc: Rich Felker > Cc: Chris Metcalf > Cc: Thomas Gleixner > Cc: Ingo Molnar > Cc: "H. Peter Anvin" > --- > arch/ia64/mm/init.c| 19 --- > arch/powerpc/mm/mem.c | 18 +++--- > arch/s390/mm/init.c| 10 -- > arch/sh/mm/init.c | 18 +++--- > arch/tile/mm/init.c| 10 -- > arch/x86/mm/init_32.c | 19 --- > arch/x86/mm/init_64.c | 19 --- > include/linux/memory_hotplug.h | 17 +++-- > kernel/memremap.c | 4 ++-- > mm/memory_hotplug.c| 4 ++-- > 10 files changed, 113 insertions(+), 25 deletions(-) > > diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c > index 1841ef6..95a2fa5 100644 > --- a/arch/ia64/mm/init.c > +++ b/arch/ia64/mm/init.c > @@ -645,7 +645,7 @@ mem_init (void) > } > > #ifdef CONFIG_MEMORY_HOTPLUG > -int arch_add_memory(int nid, u64 start, u64 size, bool for_device) > +int arch_add_memory(int nid, u64 start, u64 size, int flags) > { > pg_data_t *pgdat; > struct zone *zone; > @@ -653,10 +653,17 @@ int arch_add_memory(int nid, u64 start, u64 size, bool > for_device) > unsigned long nr_pages = size >> PAGE_SHIFT; > int ret; > > + /* Need to add support for device and unaddressable memory if needed */ > + if (flags & MEMORY_UNADDRESSABLE) { > + BUG(); > + return -EINVAL; > + } > + > pgdat = NODE_DATA(nid); > > zone = pgdat->node_zones + > - zone_for_memory(nid, start, size, ZONE_NORMAL, for_device); > + zone_for_memory(nid, start, size, ZONE_NORMAL, > + flags & MEMORY_DEVICE); > ret = __add_pages(nid, zone, start_pfn, nr_pages); > > if (ret) > @@ -667,13 +674,19 @@ int arch_add_memory(int nid, u64 start, u64 size, bool > for_device) > } > > #ifdef CONFIG_MEMORY_HOTREMOVE > -int arch_remove_memory(u64 start, u64 size) > +int arch_remove_memory(u64 start, u64 size, int flags) > { > unsigned long start_pfn = start >> PAGE_SHIFT; > unsigned long nr_pages = size >> PAGE_SHIFT; > struct zone *zone; > int ret; > > + /* Need to add support for device and unaddressable memory if needed */ > + if (flags & MEMORY_UNADDRESSABLE) { > + BUG(); > + return -EINVAL; > + } > + > zone = page_zone(pfn_to_page(start_pfn)); > ret = __remove_pages(zone, start_pfn, nr_pages); > if (ret) > diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c > index 5f84433..e3c0532 100644 > --- a/arch/powerpc/mm/mem.c > +++ b/arch/powerpc/mm/mem.c > @@ -126,7 +126,7 @@ int __weak remove_section_mapping(unsigned long start, > unsigned long end) > return -ENODEV; > } > > -int arch_add_memory(int nid, u64 start, u64 size, bool for_device) > +int arch_add_memory(int nid, u64 start, u64 size, int flags) > { > struct pglist_data *pgdata; > struct zone *zone; > @@ -134,6 +134,12 @@ int arch_add_memory(int nid, u64 start, u64 size, bool > for_device) > unsigned long nr_pages = size >> PAGE_SHIFT; > int rc; > > + /* Need to add support for device and unaddressable memory if needed */ > + if (flags & MEMORY_UNADDRESSABLE) { > + BUG(); > + return -EINVAL; > + } > + > pgdata = NODE_DATA(nid); > > start = (unsigned long)__va(start); > @@ -147,18 +153,24 @@ int arch_add_memory(int nid, u64 start, u64 size, bool > for_device) > > /* this should work for most non-highmem platforms */ > zone = pgdata->node_zones + > - zone_for_memory(nid, start, size, 0, for_device); > + zone_for_memory(nid, start, size, 0, flags & MEMORY_DEVICE); > > return __add_pages(nid, zone, start_pfn, nr_pages); > } > > #ifdef CONFIG_MEMORY_HOTREMOVE > -int arch_remove_memory(u64 start, u64 size) > +int arch_remove_memory(u64 start, u64 size,
Re: [HMM v13 01/18] mm/memory/hotplug: convert device parameter bool to set of flags
On 11/18/2016 11:48 PM, Jérôme Glisse wrote: > Only usefull for arch where we support ZONE_DEVICE and where we want to A small nit s/usefull/useful/ > also support un-addressable device memory. We need struct page for such > un-addressable memory. But we should avoid populating the kernel linear > mapping for the physical address range because there is no real memory > or anything behind those physical address. > > Hence we need more flags than just knowing if it is device memory or not. > > Signed-off-by: Jérôme Glisse > Cc: Russell King > Cc: Benjamin Herrenschmidt > Cc: Paul Mackerras > Cc: Michael Ellerman > Cc: Martin Schwidefsky > Cc: Heiko Carstens > Cc: Yoshinori Sato > Cc: Rich Felker > Cc: Chris Metcalf > Cc: Thomas Gleixner > Cc: Ingo Molnar > Cc: "H. Peter Anvin" > --- > arch/ia64/mm/init.c| 19 --- > arch/powerpc/mm/mem.c | 18 +++--- > arch/s390/mm/init.c| 10 -- > arch/sh/mm/init.c | 18 +++--- > arch/tile/mm/init.c| 10 -- > arch/x86/mm/init_32.c | 19 --- > arch/x86/mm/init_64.c | 19 --- > include/linux/memory_hotplug.h | 17 +++-- > kernel/memremap.c | 4 ++-- > mm/memory_hotplug.c| 4 ++-- > 10 files changed, 113 insertions(+), 25 deletions(-) > > diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c > index 1841ef6..95a2fa5 100644 > --- a/arch/ia64/mm/init.c > +++ b/arch/ia64/mm/init.c > @@ -645,7 +645,7 @@ mem_init (void) > } > > #ifdef CONFIG_MEMORY_HOTPLUG > -int arch_add_memory(int nid, u64 start, u64 size, bool for_device) > +int arch_add_memory(int nid, u64 start, u64 size, int flags) > { > pg_data_t *pgdat; > struct zone *zone; > @@ -653,10 +653,17 @@ int arch_add_memory(int nid, u64 start, u64 size, bool > for_device) > unsigned long nr_pages = size >> PAGE_SHIFT; > int ret; > > + /* Need to add support for device and unaddressable memory if needed */ > + if (flags & MEMORY_UNADDRESSABLE) { > + BUG(); > + return -EINVAL; > + } > + > pgdat = NODE_DATA(nid); > > zone = pgdat->node_zones + > - zone_for_memory(nid, start, size, ZONE_NORMAL, for_device); > + zone_for_memory(nid, start, size, ZONE_NORMAL, > + flags & MEMORY_DEVICE); > ret = __add_pages(nid, zone, start_pfn, nr_pages); > > if (ret) > @@ -667,13 +674,19 @@ int arch_add_memory(int nid, u64 start, u64 size, bool > for_device) > } > > #ifdef CONFIG_MEMORY_HOTREMOVE > -int arch_remove_memory(u64 start, u64 size) > +int arch_remove_memory(u64 start, u64 size, int flags) > { > unsigned long start_pfn = start >> PAGE_SHIFT; > unsigned long nr_pages = size >> PAGE_SHIFT; > struct zone *zone; > int ret; > > + /* Need to add support for device and unaddressable memory if needed */ > + if (flags & MEMORY_UNADDRESSABLE) { > + BUG(); > + return -EINVAL; > + } > + > zone = page_zone(pfn_to_page(start_pfn)); > ret = __remove_pages(zone, start_pfn, nr_pages); > if (ret) > diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c > index 5f84433..e3c0532 100644 > --- a/arch/powerpc/mm/mem.c > +++ b/arch/powerpc/mm/mem.c > @@ -126,7 +126,7 @@ int __weak remove_section_mapping(unsigned long start, > unsigned long end) > return -ENODEV; > } > > -int arch_add_memory(int nid, u64 start, u64 size, bool for_device) > +int arch_add_memory(int nid, u64 start, u64 size, int flags) > { > struct pglist_data *pgdata; > struct zone *zone; > @@ -134,6 +134,12 @@ int arch_add_memory(int nid, u64 start, u64 size, bool > for_device) > unsigned long nr_pages = size >> PAGE_SHIFT; > int rc; > > + /* Need to add support for device and unaddressable memory if needed */ > + if (flags & MEMORY_UNADDRESSABLE) { > + BUG(); > + return -EINVAL; > + } > + > pgdata = NODE_DATA(nid); > > start = (unsigned long)__va(start); > @@ -147,18 +153,24 @@ int arch_add_memory(int nid, u64 start, u64 size, bool > for_device) > > /* this should work for most non-highmem platforms */ > zone = pgdata->node_zones + > - zone_for_memory(nid, start, size, 0, for_device); > + zone_for_memory(nid, start, size, 0, flags & MEMORY_DEVICE); > > return __add_pages(nid, zone, start_pfn, nr_pages); > } > > #ifdef CONFIG_MEMORY_HOTREMOVE > -int arch_remove_memory(u64 start, u64 size) > +int arch_remove_memory(u64 start, u64 size, int flags) > { > unsigned long start_pfn = start >> PAGE_SHIFT; > unsigned long nr_pages = size >> PAGE_SHIFT; > struct zone *zone; > int ret; > + > + /* Need to add support for device and unaddressable memory if needed */ > + if (flags &
[PATCH resend] kbuild: provide include/asm/asm-prototypes.h for x86
Nicholas Piggin wrote: > Architectures will need to have an include/asm/asm-prototypes.h that > defines or #include<>s C-style prototypes for exported asm functions. > We can do an asm-generic version for the common ones like memset so > there's not a lot of pointless duplication there. Signed-off-by: Adam BorowskiTested-by: Kalle Valo --- arch/x86/include/asm/asm-prototypes.h | 12 include/asm-generic/asm-prototypes.h | 7 +++ 2 files changed, 19 insertions(+) create mode 100644 arch/x86/include/asm/asm-prototypes.h create mode 100644 include/asm-generic/asm-prototypes.h diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h new file mode 100644 index 000..ae87224 --- /dev/null +++ b/arch/x86/include/asm/asm-prototypes.h @@ -0,0 +1,12 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include diff --git a/include/asm-generic/asm-prototypes.h b/include/asm-generic/asm-prototypes.h new file mode 100644 index 000..df13637 --- /dev/null +++ b/include/asm-generic/asm-prototypes.h @@ -0,0 +1,7 @@ +#include +extern void *__memset(void *, int, __kernel_size_t); +extern void *__memcpy(void *, const void *, __kernel_size_t); +extern void *__memmove(void *, const void *, __kernel_size_t); +extern void *memset(void *, int, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t); -- 2.10.2 Nicholas Piggin wrote: > On Sun, 20 Nov 2016 19:26:23 +0100 Peter Wu wrote: > >> Current git master (v4.9-rc5-364-g77079b1) with the latest kbuild fixes >> is still failing to load modules when built with CONFIG_MODVERSIONS=y on >> x86_64 using GCC 6.2.1. >> >> It can still be reproduced with make defconfig, then enabling >> CONFIG_MODVERSIONS=y. The build output contains: >> >> WARNING: "memcpy" [net/netfilter/nf_nat.ko] has no CRC! >> WARNING: "memmove" [net/netfilter/nf_nat.ko] has no CRC! >> WARNING: "_copy_to_user" [fs/efivarfs/efivarfs.ko] has no CRC! >> WARNING: "memcpy" [fs/efivarfs/efivarfs.ko] has no CRC! >> WARNING: "_copy_from_user" [fs/efivarfs/efivarfs.ko] has no CRC! > > Sorry it's taken some time, bear with us. The arch specific patches need > to be merged now. Adam, what is the status of your patch? Please submit > to x86 maintainers if you haven't already. I've re-checked against 4.9-rc6. It'd probably fit better with kbuild parts, but it's up to you to decide; I'm sending to x86 guys as you wish. Meow!
[PATCH resend] kbuild: provide include/asm/asm-prototypes.h for x86
Nicholas Piggin wrote: > Architectures will need to have an include/asm/asm-prototypes.h that > defines or #include<>s C-style prototypes for exported asm functions. > We can do an asm-generic version for the common ones like memset so > there's not a lot of pointless duplication there. Signed-off-by: Adam Borowski Tested-by: Kalle Valo --- arch/x86/include/asm/asm-prototypes.h | 12 include/asm-generic/asm-prototypes.h | 7 +++ 2 files changed, 19 insertions(+) create mode 100644 arch/x86/include/asm/asm-prototypes.h create mode 100644 include/asm-generic/asm-prototypes.h diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h new file mode 100644 index 000..ae87224 --- /dev/null +++ b/arch/x86/include/asm/asm-prototypes.h @@ -0,0 +1,12 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include diff --git a/include/asm-generic/asm-prototypes.h b/include/asm-generic/asm-prototypes.h new file mode 100644 index 000..df13637 --- /dev/null +++ b/include/asm-generic/asm-prototypes.h @@ -0,0 +1,7 @@ +#include +extern void *__memset(void *, int, __kernel_size_t); +extern void *__memcpy(void *, const void *, __kernel_size_t); +extern void *__memmove(void *, const void *, __kernel_size_t); +extern void *memset(void *, int, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t); -- 2.10.2 Nicholas Piggin wrote: > On Sun, 20 Nov 2016 19:26:23 +0100 Peter Wu wrote: > >> Current git master (v4.9-rc5-364-g77079b1) with the latest kbuild fixes >> is still failing to load modules when built with CONFIG_MODVERSIONS=y on >> x86_64 using GCC 6.2.1. >> >> It can still be reproduced with make defconfig, then enabling >> CONFIG_MODVERSIONS=y. The build output contains: >> >> WARNING: "memcpy" [net/netfilter/nf_nat.ko] has no CRC! >> WARNING: "memmove" [net/netfilter/nf_nat.ko] has no CRC! >> WARNING: "_copy_to_user" [fs/efivarfs/efivarfs.ko] has no CRC! >> WARNING: "memcpy" [fs/efivarfs/efivarfs.ko] has no CRC! >> WARNING: "_copy_from_user" [fs/efivarfs/efivarfs.ko] has no CRC! > > Sorry it's taken some time, bear with us. The arch specific patches need > to be merged now. Adam, what is the status of your patch? Please submit > to x86 maintainers if you haven't already. I've re-checked against 4.9-rc6. It'd probably fit better with kbuild parts, but it's up to you to decide; I'm sending to x86 guys as you wish. Meow!
[GIT PULL][SECURITY] Apparmor bugfix
Please pull this fix for 4.9. >From JJ: "This is a fix for a policy replacement bug that is fairly serious for apache mod_apparmor users, as it results in the wrong policy being applied on an network facing service." The following changes since commit 9c763584b7c8911106bb77af7e648bef09af9d80: Linux 4.9-rc6 (2016-11-20 13:52:19 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git for-linus John Johansen (1): apparmor: fix change_hat not finding hat after policy replacement security/apparmor/domain.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) --- commit 3d40658c977769ce2138f286cf131537bf68bdfe Author: John JohansenDate: Wed Aug 31 21:10:06 2016 -0700 apparmor: fix change_hat not finding hat after policy replacement After a policy replacement, the task cred may be out of date and need to be updated. However change_hat is using the stale profiles from the out of date cred resulting in either: a stale profile being applied or, incorrect failure when searching for a hat profile as it has been migrated to the new parent profile. Fixes: 01e2b670aa898a39259bc85c78e3d74820f4d3b6 (failure to find hat) Fixes: 898127c34ec03291c86f4ff3856d79e9e18952bc (stale policy being applied) Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000287 Cc: sta...@vger.kernel.org Signed-off-by: John Johansen Signed-off-by: James Morris diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index fc3036b..a4d90aa 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -621,8 +621,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) /* released below */ cred = get_current_cred(); cxt = cred_cxt(cred); - profile = aa_cred_profile(cred); - previous_profile = cxt->previous; + profile = aa_get_newest_profile(aa_cred_profile(cred)); + previous_profile = aa_get_newest_profile(cxt->previous); if (unconfined(profile)) { info = "unconfined"; @@ -718,6 +718,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) out: aa_put_profile(hat); kfree(name); + aa_put_profile(profile); + aa_put_profile(previous_profile); put_cred(cred); return error;
[GIT PULL][SECURITY] Apparmor bugfix
Please pull this fix for 4.9. >From JJ: "This is a fix for a policy replacement bug that is fairly serious for apache mod_apparmor users, as it results in the wrong policy being applied on an network facing service." The following changes since commit 9c763584b7c8911106bb77af7e648bef09af9d80: Linux 4.9-rc6 (2016-11-20 13:52:19 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git for-linus John Johansen (1): apparmor: fix change_hat not finding hat after policy replacement security/apparmor/domain.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) --- commit 3d40658c977769ce2138f286cf131537bf68bdfe Author: John Johansen Date: Wed Aug 31 21:10:06 2016 -0700 apparmor: fix change_hat not finding hat after policy replacement After a policy replacement, the task cred may be out of date and need to be updated. However change_hat is using the stale profiles from the out of date cred resulting in either: a stale profile being applied or, incorrect failure when searching for a hat profile as it has been migrated to the new parent profile. Fixes: 01e2b670aa898a39259bc85c78e3d74820f4d3b6 (failure to find hat) Fixes: 898127c34ec03291c86f4ff3856d79e9e18952bc (stale policy being applied) Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000287 Cc: sta...@vger.kernel.org Signed-off-by: John Johansen Signed-off-by: James Morris diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index fc3036b..a4d90aa 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -621,8 +621,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) /* released below */ cred = get_current_cred(); cxt = cred_cxt(cred); - profile = aa_cred_profile(cred); - previous_profile = cxt->previous; + profile = aa_get_newest_profile(aa_cred_profile(cred)); + previous_profile = aa_get_newest_profile(cxt->previous); if (unconfined(profile)) { info = "unconfined"; @@ -718,6 +718,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) out: aa_put_profile(hat); kfree(name); + aa_put_profile(profile); + aa_put_profile(previous_profile); put_cred(cred); return error;
Re: perf TUI fails with "failed to process type: 64"
Hi, I forgot about the set of issues below. Michael had a suggested powerpc fix for 3, but it it would be nice to fix the perf bugs in 1 and 2. Anton -- > Updating to mainline as of last night, I started seeing the following > error when running the perf report TUI: > > 0x46068 [0x8]: failed to process type: 68 > > This event is just PERF_RECORD_FINISHED_ROUND: > > 0x46068 [0x8]: event: 68 > . > . ... raw event: size 8 bytes > . : 44 00 00 00 00 00 08 00 > D... > > 0x46068 [0x8]: PERF_RECORD_FINISHED_ROUND > > Which of course is not our error. It took me a while to find the real > culprit: > > 14c00-14c00 g exc_virt_0x4c00_system_call > > A zero length symbol, which __symbol__inc_addr_samples() barfs on: > > if (addr < sym->start || addr >= sym->end) { > ... > return -ERANGE; > > Seems like we have 3 bugs here: > > 1. Output the real source of the error instead of > PERF_RECORD_FINISHED_ROUND > > 2. Don't exit the TUI if we find a sample on a zero length symbol > > 3. Why do we have zero length symbols in the first place? Does the > recent ppc64 exception clean up have something to do with it? > > Anton
Re: perf TUI fails with "failed to process type: 64"
Hi, I forgot about the set of issues below. Michael had a suggested powerpc fix for 3, but it it would be nice to fix the perf bugs in 1 and 2. Anton -- > Updating to mainline as of last night, I started seeing the following > error when running the perf report TUI: > > 0x46068 [0x8]: failed to process type: 68 > > This event is just PERF_RECORD_FINISHED_ROUND: > > 0x46068 [0x8]: event: 68 > . > . ... raw event: size 8 bytes > . : 44 00 00 00 00 00 08 00 > D... > > 0x46068 [0x8]: PERF_RECORD_FINISHED_ROUND > > Which of course is not our error. It took me a while to find the real > culprit: > > 14c00-14c00 g exc_virt_0x4c00_system_call > > A zero length symbol, which __symbol__inc_addr_samples() barfs on: > > if (addr < sym->start || addr >= sym->end) { > ... > return -ERANGE; > > Seems like we have 3 bugs here: > > 1. Output the real source of the error instead of > PERF_RECORD_FINISHED_ROUND > > 2. Don't exit the TUI if we find a sample on a zero length symbol > > 3. Why do we have zero length symbols in the first place? Does the > recent ppc64 exception clean up have something to do with it? > > Anton
[PATCH v2 1/2] usb: host: plat: Enable xhci plat runtime PM
Enable the xhci plat runtime PM for parent device to suspend/resume xhci. Signed-off-by: Baolin Wang--- Changes since v1: - No updates. --- drivers/usb/host/xhci-plat.c | 37 - 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index ed56bf9..13f86ad 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -246,6 +246,9 @@ static int xhci_plat_probe(struct platform_device *pdev) if (ret) goto dealloc_usb2_hcd; + pm_runtime_set_active(>dev); + pm_runtime_enable(>dev); + return 0; @@ -274,6 +277,7 @@ static int xhci_plat_remove(struct platform_device *dev) struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct clk *clk = xhci->clk; + pm_runtime_disable(>dev); usb_remove_hcd(xhci->shared_hcd); usb_phy_shutdown(hcd->usb_phy); @@ -311,14 +315,37 @@ static int xhci_plat_resume(struct device *dev) return xhci_resume(xhci, 0); } +#endif /* CONFIG_PM_SLEEP */ + +#ifdef CONFIG_PM +static int xhci_plat_runtime_suspend(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + return xhci_suspend(xhci, device_may_wakeup(dev)); +} + +static int xhci_plat_runtime_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + return xhci_resume(xhci, 0); +} + +static int xhci_plat_runtime_idle(struct device *dev) +{ + return 0; +} +#endif /* CONFIG_PM */ static const struct dev_pm_ops xhci_plat_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume) + + SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, xhci_plat_runtime_resume, + xhci_plat_runtime_idle) }; -#define DEV_PM_OPS (_plat_pm_ops) -#else -#define DEV_PM_OPS NULL -#endif /* CONFIG_PM */ static const struct acpi_device_id usb_xhci_acpi_match[] = { /* XHCI-compliant USB Controller */ @@ -332,7 +359,7 @@ static int xhci_plat_resume(struct device *dev) .remove = xhci_plat_remove, .driver = { .name = "xhci-hcd", - .pm = DEV_PM_OPS, + .pm = _plat_pm_ops, .of_match_table = of_match_ptr(usb_xhci_of_match), .acpi_match_table = ACPI_PTR(usb_xhci_acpi_match), }, -- 1.7.9.5
[PATCH v2 1/2] usb: host: plat: Enable xhci plat runtime PM
Enable the xhci plat runtime PM for parent device to suspend/resume xhci. Signed-off-by: Baolin Wang --- Changes since v1: - No updates. --- drivers/usb/host/xhci-plat.c | 37 - 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index ed56bf9..13f86ad 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -246,6 +246,9 @@ static int xhci_plat_probe(struct platform_device *pdev) if (ret) goto dealloc_usb2_hcd; + pm_runtime_set_active(>dev); + pm_runtime_enable(>dev); + return 0; @@ -274,6 +277,7 @@ static int xhci_plat_remove(struct platform_device *dev) struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct clk *clk = xhci->clk; + pm_runtime_disable(>dev); usb_remove_hcd(xhci->shared_hcd); usb_phy_shutdown(hcd->usb_phy); @@ -311,14 +315,37 @@ static int xhci_plat_resume(struct device *dev) return xhci_resume(xhci, 0); } +#endif /* CONFIG_PM_SLEEP */ + +#ifdef CONFIG_PM +static int xhci_plat_runtime_suspend(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + return xhci_suspend(xhci, device_may_wakeup(dev)); +} + +static int xhci_plat_runtime_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + return xhci_resume(xhci, 0); +} + +static int xhci_plat_runtime_idle(struct device *dev) +{ + return 0; +} +#endif /* CONFIG_PM */ static const struct dev_pm_ops xhci_plat_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume) + + SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, xhci_plat_runtime_resume, + xhci_plat_runtime_idle) }; -#define DEV_PM_OPS (_plat_pm_ops) -#else -#define DEV_PM_OPS NULL -#endif /* CONFIG_PM */ static const struct acpi_device_id usb_xhci_acpi_match[] = { /* XHCI-compliant USB Controller */ @@ -332,7 +359,7 @@ static int xhci_plat_resume(struct device *dev) .remove = xhci_plat_remove, .driver = { .name = "xhci-hcd", - .pm = DEV_PM_OPS, + .pm = _plat_pm_ops, .of_match_table = of_match_ptr(usb_xhci_of_match), .acpi_match_table = ACPI_PTR(usb_xhci_acpi_match), }, -- 1.7.9.5
[PATCH v2 2/2] usb: dwc3: core: Support the dwc3 host suspend/resume
For some mobile devices with strict power management, we also want to suspend the host when the slave is detached for power saving. Thus we add the host suspend/resume functions to support this requirement. Signed-off-by: Baolin Wang--- Changes since v1: - Add pm_runtime.h head file to avoid kbuild error. --- drivers/usb/dwc3/Kconfig |7 ++ drivers/usb/dwc3/core.c | 26 +- drivers/usb/dwc3/core.h | 15 + drivers/usb/dwc3/host.c | 54 ++ 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index a45b4f1..47bb2f3 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -47,6 +47,13 @@ config USB_DWC3_DUAL_ROLE endchoice +config USB_DWC3_HOST_SUSPEND + bool "Choose if the DWC3 host (xhci) can be suspend/resume" + depends on USB_DWC3_HOST=y || USB_DWC3_DUAL_ROLE=y + help + We can suspend the host when the slave is detached for power saving, + and resume the host when one slave is attached. + comment "Platform Glue Driver Support" config USB_DWC3_OMAP diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 9a4a5e4..7ad4bc3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1091,6 +1091,7 @@ static int dwc3_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY); pm_runtime_enable(dev); + pm_suspend_ignore_children(dev, true); ret = pm_runtime_get_sync(dev); if (ret < 0) goto err1; @@ -1215,15 +1216,27 @@ static int dwc3_remove(struct platform_device *pdev) static int dwc3_suspend_common(struct dwc3 *dwc) { unsigned long flags; + int ret; switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: + spin_lock_irqsave(>lock, flags); + dwc3_gadget_suspend(dwc); + spin_unlock_irqrestore(>lock, flags); + break; case USB_DR_MODE_OTG: + ret = dwc3_host_suspend(dwc); + if (ret) + return ret; + spin_lock_irqsave(>lock, flags); dwc3_gadget_suspend(dwc); spin_unlock_irqrestore(>lock, flags); break; case USB_DR_MODE_HOST: + ret = dwc3_host_suspend(dwc); + if (ret) + return ret; default: /* do nothing */ break; @@ -1245,12 +1258,23 @@ static int dwc3_resume_common(struct dwc3 *dwc) switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: + spin_lock_irqsave(>lock, flags); + dwc3_gadget_resume(dwc); + spin_unlock_irqrestore(>lock, flags); + break; case USB_DR_MODE_OTG: + ret = dwc3_host_resume(dwc); + if (ret) + return ret; + spin_lock_irqsave(>lock, flags); dwc3_gadget_resume(dwc); spin_unlock_irqrestore(>lock, flags); - /* FALLTHROUGH */ + break; case USB_DR_MODE_HOST: + ret = dwc3_host_resume(dwc); + if (ret) + return ret; default: /* do nothing */ break; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index b585a30..db41908 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1226,4 +1226,19 @@ static inline void dwc3_ulpi_exit(struct dwc3 *dwc) { } #endif +#if IS_ENABLED(CONFIG_USB_DWC3_HOST_SUSPEND) +int dwc3_host_suspend(struct dwc3 *dwc); +int dwc3_host_resume(struct dwc3 *dwc); +#else +static inline int dwc3_host_suspend(struct dwc3 *dwc) +{ + return 0; +} + +static inline int dwc3_host_resume(struct dwc3 *dwc) +{ + return 0; +} +#endif + #endif /* __DRIVERS_USB_DWC3_CORE_H */ diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index ed82464..20e84fc 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -16,9 +16,13 @@ */ #include +#include #include "core.h" +#define DWC3_HOST_SUSPEND_COUNT100 +#define DWC3_HOST_SUSPEND_TIMEOUT 100 + static int dwc3_host_get_irq(struct dwc3 *dwc) { struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); @@ -130,3 +134,53 @@ void dwc3_host_exit(struct dwc3 *dwc) dev_name(>xhci->dev)); platform_device_unregister(dwc->xhci); } + +#ifdef CONFIG_USB_DWC3_HOST_SUSPEND +int dwc3_host_suspend(struct dwc3 *dwc) +{ + struct device *xhci = >xhci->dev; + int ret, cnt = DWC3_HOST_SUSPEND_COUNT; + + /* +* We need make sure the children of the xHCI device had been into +* suspend
[PATCH v2 2/2] usb: dwc3: core: Support the dwc3 host suspend/resume
For some mobile devices with strict power management, we also want to suspend the host when the slave is detached for power saving. Thus we add the host suspend/resume functions to support this requirement. Signed-off-by: Baolin Wang --- Changes since v1: - Add pm_runtime.h head file to avoid kbuild error. --- drivers/usb/dwc3/Kconfig |7 ++ drivers/usb/dwc3/core.c | 26 +- drivers/usb/dwc3/core.h | 15 + drivers/usb/dwc3/host.c | 54 ++ 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index a45b4f1..47bb2f3 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -47,6 +47,13 @@ config USB_DWC3_DUAL_ROLE endchoice +config USB_DWC3_HOST_SUSPEND + bool "Choose if the DWC3 host (xhci) can be suspend/resume" + depends on USB_DWC3_HOST=y || USB_DWC3_DUAL_ROLE=y + help + We can suspend the host when the slave is detached for power saving, + and resume the host when one slave is attached. + comment "Platform Glue Driver Support" config USB_DWC3_OMAP diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 9a4a5e4..7ad4bc3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1091,6 +1091,7 @@ static int dwc3_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY); pm_runtime_enable(dev); + pm_suspend_ignore_children(dev, true); ret = pm_runtime_get_sync(dev); if (ret < 0) goto err1; @@ -1215,15 +1216,27 @@ static int dwc3_remove(struct platform_device *pdev) static int dwc3_suspend_common(struct dwc3 *dwc) { unsigned long flags; + int ret; switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: + spin_lock_irqsave(>lock, flags); + dwc3_gadget_suspend(dwc); + spin_unlock_irqrestore(>lock, flags); + break; case USB_DR_MODE_OTG: + ret = dwc3_host_suspend(dwc); + if (ret) + return ret; + spin_lock_irqsave(>lock, flags); dwc3_gadget_suspend(dwc); spin_unlock_irqrestore(>lock, flags); break; case USB_DR_MODE_HOST: + ret = dwc3_host_suspend(dwc); + if (ret) + return ret; default: /* do nothing */ break; @@ -1245,12 +1258,23 @@ static int dwc3_resume_common(struct dwc3 *dwc) switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: + spin_lock_irqsave(>lock, flags); + dwc3_gadget_resume(dwc); + spin_unlock_irqrestore(>lock, flags); + break; case USB_DR_MODE_OTG: + ret = dwc3_host_resume(dwc); + if (ret) + return ret; + spin_lock_irqsave(>lock, flags); dwc3_gadget_resume(dwc); spin_unlock_irqrestore(>lock, flags); - /* FALLTHROUGH */ + break; case USB_DR_MODE_HOST: + ret = dwc3_host_resume(dwc); + if (ret) + return ret; default: /* do nothing */ break; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index b585a30..db41908 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1226,4 +1226,19 @@ static inline void dwc3_ulpi_exit(struct dwc3 *dwc) { } #endif +#if IS_ENABLED(CONFIG_USB_DWC3_HOST_SUSPEND) +int dwc3_host_suspend(struct dwc3 *dwc); +int dwc3_host_resume(struct dwc3 *dwc); +#else +static inline int dwc3_host_suspend(struct dwc3 *dwc) +{ + return 0; +} + +static inline int dwc3_host_resume(struct dwc3 *dwc) +{ + return 0; +} +#endif + #endif /* __DRIVERS_USB_DWC3_CORE_H */ diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index ed82464..20e84fc 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -16,9 +16,13 @@ */ #include +#include #include "core.h" +#define DWC3_HOST_SUSPEND_COUNT100 +#define DWC3_HOST_SUSPEND_TIMEOUT 100 + static int dwc3_host_get_irq(struct dwc3 *dwc) { struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); @@ -130,3 +134,53 @@ void dwc3_host_exit(struct dwc3 *dwc) dev_name(>xhci->dev)); platform_device_unregister(dwc->xhci); } + +#ifdef CONFIG_USB_DWC3_HOST_SUSPEND +int dwc3_host_suspend(struct dwc3 *dwc) +{ + struct device *xhci = >xhci->dev; + int ret, cnt = DWC3_HOST_SUSPEND_COUNT; + + /* +* We need make sure the children of the xHCI device had been into +* suspend state, or we will
RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family flash
On Thu, Nov 18, 2016 at 07:00 PM +, Krzeminski, Marcin (Nokia - PL/Wroclaw) wrote: > > -Original Message- > > From: Yao Yuan [mailto:yao.y...@nxp.com] > > Sent: Friday, November 18, 2016 5:20 AM > > To: Krzeminski, Marcin (Nokia - PL/Wroclaw) > >; Han Xu > > Cc: David Woodhouse ; linux- > > ker...@vger.kernel.org; linux-...@lists.infradead.org; > > han...@freescale.com; Brian Norris ; > > jagannadh.t...@gmail.com; linux-arm-ker...@lists.infradead.org > > Subject: RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S > > family flash > > > > On Thu, Nov 17, 2016 at 10:14:55AM +, Krzeminski, Marcin (Nokia - > > PL/Wroclaw) wrote: > > > > On Thu, Nov 17, 2016 at 06:50:55AM +, Krzeminski, Marcin > > > > (Nokia > > > > - > > > > PL/Wroclaw) wrote: > > > > > > > > On Thu, Aug 18, 2016 at 2:38 AM, Yunhui Cui > > > > > > > > > > > > > > > > wrote: > > > > > > > > > From: Yunhui Cui > > > > > > > > > > > > > > > > > > With the physical sectors combination, S25FS-S family > > > > > > > > > flash requires some special operations for read/write > > > > > > > > > functions. > > > > > > > > > > > > > > > > > > Signed-off-by: Yunhui Cui > > > > > > > > > --- > > > > > > > > > drivers/mtd/spi-nor/spi-nor.c | 56 > > > > > > > > > +++ > > > > > > > > > 1 file changed, 56 insertions(+) > > > > > > > > > > > > > > > > > > diff --git a/drivers/mtd/spi-nor/spi-nor.c > > > > > > > > > b/drivers/mtd/spi-nor/spi-nor.c index d0fc165..495d0bb > > > > > > > > > 100644 > > > > > > > > > --- a/drivers/mtd/spi-nor/spi-nor.c > > > > > > > > > +++ b/drivers/mtd/spi-nor/spi-nor.c > > > > > > > > > @@ -39,6 +39,10 @@ > > > > > > > > > > > > > > > > > > #define SPI_NOR_MAX_ID_LEN 6 > > > > > > > > > #define SPI_NOR_MAX_ADDR_WIDTH 4 > > > > > > > > > +/* Added for S25FS-S family flash */ > > > > > > > > > +#define SPINOR_CONFIG_REG3_OFFSET 0x84 > > > > > > > > > +#define CR3V_4KB_ERASE_UNABLE 0x8 #define > > > > > > > > > +SPINOR_S25FS_FAMILY_EXT_JEDEC 0x81 > > > > > > > > > > > > > > > > > > struct flash_info { > > > > > > > > > char*name; > > > > > > > > > @@ -78,6 +82,7 @@ struct flash_info { }; > > > > > > > > > > > > > > > > > > #define JEDEC_MFR(info)((info)->id[0]) > > > > > > > > > +#define EXT_JEDEC(info)((info)->id[5]) > > > > > > > > > > > > > > > > > > static const struct flash_info *spi_nor_match_id(const > > > > > > > > > char *name); > > > > > > > > > > > > > > > > > > @@ -899,6 +904,7 @@ static const struct flash_info > > spi_nor_ids[] = { > > > > > > > > > */ > > > > > > > > > { "s25sl032p", INFO(0x010215, 0x4d00, 64 * > > > > > > > > > 1024, 64, > > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > > > > > > > > > { "s25sl064p", INFO(0x010216, 0x4d00, 64 * > > > > > > > > > 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > > > > > > > > > + { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * > > > > > > > > > + 1024, 512, 0)}, > > > > > > > > > { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, > > > > > > > > > 128, 0) }, > > > > > > > > > { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * > > > > > > > > > 1024, 512, > > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > > > > > > > > > { "s25fl512s", INFO(0x010220, 0x4d00, 256 * > > > > > > > > > 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > @@ > > > > > > > > > - > > 1036,6 > > > > > > +1042,50 > > > > > > > > @@ static const struct flash_info *spi_nor_read_id(struct > > > > > > > > spi_nor > > > > > > > > *nor) > > > > > > > > > return ERR_PTR(-ENODEV); } > > > > > > > > > > > > > > > > > > +/* > > > > > > > > > + * The S25FS-S family physical sectors may be > > > > > > > > > +configured as a > > > > > > > > > + * hybrid combination of eight 4-kB parameter sectors > > > > > > > > > + * at the top or bottom of the address space with all > > > > > > > > > + * but one of the remaining sectors being uniform size. > > > > > > > > > + * The Parameter Sector Erase commands (20h or 21h) > > > > > > > > > +must > > > > > > > > > + * be used to erase the 4-kB parameter sectors individually. > > > > > > > > > + * The Sector (uniform sector) Erase commands (D8h or > > > > > > > > > +DCh) > > > > > > > > > + * must be used to erase any of the remaining > > > > > > > > > + * sectors, including the portion of highest or lowest > > > > > > > > > +address > > > > > > > > > + * sector that is not overlaid by the parameter sectors. > > > > > > > > > + * The uniform sector erase command has no effect on > > > > > > > > > +parameter > > > > > > > > sectors. > > > > > > > > > + */ > > > > > > > > > +static int spansion_s25fs_disable_4kb_erase(struct > > > > > > > > > +spi_nor > > *nor) { > > > > > > > > > + u32
RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family flash
On Thu, Nov 18, 2016 at 07:00 PM +, Krzeminski, Marcin (Nokia - PL/Wroclaw) wrote: > > -Original Message- > > From: Yao Yuan [mailto:yao.y...@nxp.com] > > Sent: Friday, November 18, 2016 5:20 AM > > To: Krzeminski, Marcin (Nokia - PL/Wroclaw) > > ; Han Xu > > Cc: David Woodhouse ; linux- > > ker...@vger.kernel.org; linux-...@lists.infradead.org; > > han...@freescale.com; Brian Norris ; > > jagannadh.t...@gmail.com; linux-arm-ker...@lists.infradead.org > > Subject: RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S > > family flash > > > > On Thu, Nov 17, 2016 at 10:14:55AM +, Krzeminski, Marcin (Nokia - > > PL/Wroclaw) wrote: > > > > On Thu, Nov 17, 2016 at 06:50:55AM +, Krzeminski, Marcin > > > > (Nokia > > > > - > > > > PL/Wroclaw) wrote: > > > > > > > > On Thu, Aug 18, 2016 at 2:38 AM, Yunhui Cui > > > > > > > > > > > > > > > > wrote: > > > > > > > > > From: Yunhui Cui > > > > > > > > > > > > > > > > > > With the physical sectors combination, S25FS-S family > > > > > > > > > flash requires some special operations for read/write > > > > > > > > > functions. > > > > > > > > > > > > > > > > > > Signed-off-by: Yunhui Cui > > > > > > > > > --- > > > > > > > > > drivers/mtd/spi-nor/spi-nor.c | 56 > > > > > > > > > +++ > > > > > > > > > 1 file changed, 56 insertions(+) > > > > > > > > > > > > > > > > > > diff --git a/drivers/mtd/spi-nor/spi-nor.c > > > > > > > > > b/drivers/mtd/spi-nor/spi-nor.c index d0fc165..495d0bb > > > > > > > > > 100644 > > > > > > > > > --- a/drivers/mtd/spi-nor/spi-nor.c > > > > > > > > > +++ b/drivers/mtd/spi-nor/spi-nor.c > > > > > > > > > @@ -39,6 +39,10 @@ > > > > > > > > > > > > > > > > > > #define SPI_NOR_MAX_ID_LEN 6 > > > > > > > > > #define SPI_NOR_MAX_ADDR_WIDTH 4 > > > > > > > > > +/* Added for S25FS-S family flash */ > > > > > > > > > +#define SPINOR_CONFIG_REG3_OFFSET 0x84 > > > > > > > > > +#define CR3V_4KB_ERASE_UNABLE 0x8 #define > > > > > > > > > +SPINOR_S25FS_FAMILY_EXT_JEDEC 0x81 > > > > > > > > > > > > > > > > > > struct flash_info { > > > > > > > > > char*name; > > > > > > > > > @@ -78,6 +82,7 @@ struct flash_info { }; > > > > > > > > > > > > > > > > > > #define JEDEC_MFR(info)((info)->id[0]) > > > > > > > > > +#define EXT_JEDEC(info)((info)->id[5]) > > > > > > > > > > > > > > > > > > static const struct flash_info *spi_nor_match_id(const > > > > > > > > > char *name); > > > > > > > > > > > > > > > > > > @@ -899,6 +904,7 @@ static const struct flash_info > > spi_nor_ids[] = { > > > > > > > > > */ > > > > > > > > > { "s25sl032p", INFO(0x010215, 0x4d00, 64 * > > > > > > > > > 1024, 64, > > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > > > > > > > > > { "s25sl064p", INFO(0x010216, 0x4d00, 64 * > > > > > > > > > 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > > > > > > > > > + { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * > > > > > > > > > + 1024, 512, 0)}, > > > > > > > > > { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, > > > > > > > > > 128, 0) }, > > > > > > > > > { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * > > > > > > > > > 1024, 512, > > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > > > > > > > > > { "s25fl512s", INFO(0x010220, 0x4d00, 256 * > > > > > > > > > 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > @@ > > > > > > > > > - > > 1036,6 > > > > > > +1042,50 > > > > > > > > @@ static const struct flash_info *spi_nor_read_id(struct > > > > > > > > spi_nor > > > > > > > > *nor) > > > > > > > > > return ERR_PTR(-ENODEV); } > > > > > > > > > > > > > > > > > > +/* > > > > > > > > > + * The S25FS-S family physical sectors may be > > > > > > > > > +configured as a > > > > > > > > > + * hybrid combination of eight 4-kB parameter sectors > > > > > > > > > + * at the top or bottom of the address space with all > > > > > > > > > + * but one of the remaining sectors being uniform size. > > > > > > > > > + * The Parameter Sector Erase commands (20h or 21h) > > > > > > > > > +must > > > > > > > > > + * be used to erase the 4-kB parameter sectors individually. > > > > > > > > > + * The Sector (uniform sector) Erase commands (D8h or > > > > > > > > > +DCh) > > > > > > > > > + * must be used to erase any of the remaining > > > > > > > > > + * sectors, including the portion of highest or lowest > > > > > > > > > +address > > > > > > > > > + * sector that is not overlaid by the parameter sectors. > > > > > > > > > + * The uniform sector erase command has no effect on > > > > > > > > > +parameter > > > > > > > > sectors. > > > > > > > > > + */ > > > > > > > > > +static int spansion_s25fs_disable_4kb_erase(struct > > > > > > > > > +spi_nor > > *nor) { > > > > > > > > > + u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET; > > > > > > > > > + u8 cr3v = 0x0; > > > > > > > > > + int ret = 0x0; > > > > > > > > > + > > > > > > > > > +
Re: [PATCH 2/2] usb: dwc3: core: Support the dwc3 host suspend/resume
On 18 November 2016 at 21:14, kbuild test robotwrote: > Hi Baolin, > > [auto build test ERROR on next-20161117] > [cannot apply to balbi-usb/next usb/usb-testing v4.9-rc5 v4.9-rc4 v4.9-rc3 > v4.9-rc5] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Baolin-Wang/usb-host-plat-Enable-xhci-plat-runtime-PM/20161118-202029 > config: i386-allmodconfig (attached as .config) > compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 > reproduce: > # save the attached .config to linux build tree > make ARCH=i386 > > All errors (new ones prefixed by >>): > >drivers/usb/dwc3/host.c: In function 'dwc3_host_suspend': >>> drivers/usb/dwc3/host.c:157:10: error: implicit declaration of function >>> 'pm_children_suspended' [-Werror=implicit-function-declaration] > while (!pm_children_suspended(xhci) && --cnt > 0) > ^ >cc1: some warnings being treated as errors > > vim +/pm_children_suspended +157 drivers/usb/dwc3/host.c > >151 int ret, cnt = DWC3_HOST_SUSPEND_COUNT; >152 >153 /* >154 * We need make sure the children of the xHCI device had been > into >155 * suspend state, or we will suspend xHCI device failed. >156 */ > > 157 while (!pm_children_suspended(xhci) && --cnt > 0) >158 msleep(DWC3_HOST_SUSPEND_TIMEOUT); >159 >160 if (cnt <= 0) { I will send out new patch to fix this building error. -- Baolin.wang Best Regards
Re: [PATCH 2/2] usb: dwc3: core: Support the dwc3 host suspend/resume
On 18 November 2016 at 21:14, kbuild test robot wrote: > Hi Baolin, > > [auto build test ERROR on next-20161117] > [cannot apply to balbi-usb/next usb/usb-testing v4.9-rc5 v4.9-rc4 v4.9-rc3 > v4.9-rc5] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Baolin-Wang/usb-host-plat-Enable-xhci-plat-runtime-PM/20161118-202029 > config: i386-allmodconfig (attached as .config) > compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 > reproduce: > # save the attached .config to linux build tree > make ARCH=i386 > > All errors (new ones prefixed by >>): > >drivers/usb/dwc3/host.c: In function 'dwc3_host_suspend': >>> drivers/usb/dwc3/host.c:157:10: error: implicit declaration of function >>> 'pm_children_suspended' [-Werror=implicit-function-declaration] > while (!pm_children_suspended(xhci) && --cnt > 0) > ^ >cc1: some warnings being treated as errors > > vim +/pm_children_suspended +157 drivers/usb/dwc3/host.c > >151 int ret, cnt = DWC3_HOST_SUSPEND_COUNT; >152 >153 /* >154 * We need make sure the children of the xHCI device had been > into >155 * suspend state, or we will suspend xHCI device failed. >156 */ > > 157 while (!pm_children_suspended(xhci) && --cnt > 0) >158 msleep(DWC3_HOST_SUSPEND_TIMEOUT); >159 >160 if (cnt <= 0) { I will send out new patch to fix this building error. -- Baolin.wang Best Regards
[PATCH] vfio: fix vfio_info_cap_add/shift
Capability header next field is an offset relative to the start of the INFO buffer. tmp->next is assigned the proper value but iterations implemented in vfio_info_cap_add and vfio_info_cap_shift use next as an offset between the headers. When coping with multiple capabilities this leads to an Oops. Signed-off-by: Eric Auger--- drivers/vfio/vfio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index d1d70e0..1e838d1 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -1763,7 +1763,7 @@ struct vfio_info_cap_header *vfio_info_cap_add(struct vfio_info_cap *caps, header->version = version; /* Add to the end of the capability chain */ - for (tmp = caps->buf; tmp->next; tmp = (void *)tmp + tmp->next) + for (tmp = buf; tmp->next; tmp = buf + tmp->next) ; /* nothing */ tmp->next = caps->size; @@ -1776,8 +1776,9 @@ EXPORT_SYMBOL_GPL(vfio_info_cap_add); void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset) { struct vfio_info_cap_header *tmp; + void *buf = (void *)caps->buf; - for (tmp = caps->buf; tmp->next; tmp = (void *)tmp + tmp->next - offset) + for (tmp = buf; tmp->next; tmp = buf + tmp->next - offset) tmp->next += offset; } EXPORT_SYMBOL_GPL(vfio_info_cap_shift); -- 2.5.5
[PATCH] vfio: fix vfio_info_cap_add/shift
Capability header next field is an offset relative to the start of the INFO buffer. tmp->next is assigned the proper value but iterations implemented in vfio_info_cap_add and vfio_info_cap_shift use next as an offset between the headers. When coping with multiple capabilities this leads to an Oops. Signed-off-by: Eric Auger --- drivers/vfio/vfio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index d1d70e0..1e838d1 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -1763,7 +1763,7 @@ struct vfio_info_cap_header *vfio_info_cap_add(struct vfio_info_cap *caps, header->version = version; /* Add to the end of the capability chain */ - for (tmp = caps->buf; tmp->next; tmp = (void *)tmp + tmp->next) + for (tmp = buf; tmp->next; tmp = buf + tmp->next) ; /* nothing */ tmp->next = caps->size; @@ -1776,8 +1776,9 @@ EXPORT_SYMBOL_GPL(vfio_info_cap_add); void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset) { struct vfio_info_cap_header *tmp; + void *buf = (void *)caps->buf; - for (tmp = caps->buf; tmp->next; tmp = (void *)tmp + tmp->next - offset) + for (tmp = buf; tmp->next; tmp = buf + tmp->next - offset) tmp->next += offset; } EXPORT_SYMBOL_GPL(vfio_info_cap_shift); -- 2.5.5
[PATCH v5 2/9] IB/core: Replace semaphore sm_sem with an atomic wait
The semaphore 'sm_sem' is used for an exclusive ownership of the device so model the same as an atomic variable with an associated wait_event. Semaphores are going away in the future. Signed-off-by: Binoy Jayan--- drivers/infiniband/core/user_mad.c | 20 ++-- 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 415a318..6101c0a 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -67,6 +67,8 @@ enum { IB_UMAD_MINOR_BASE = 0 }; +#define UMAD_F_CLAIM 0x01 + /* * Our lifetime rules for these structs are the following: * device special file is opened, we take a reference on the @@ -87,7 +89,8 @@ struct ib_umad_port { struct cdev sm_cdev; struct device *sm_dev; - struct semaphore sm_sem; + wait_queue_head_t wq; + unsigned long flags; struct mutex file_mutex; struct list_head file_list; @@ -1030,12 +1033,14 @@ static int ib_umad_sm_open(struct inode *inode, struct file *filp) port = container_of(inode->i_cdev, struct ib_umad_port, sm_cdev); if (filp->f_flags & O_NONBLOCK) { - if (down_trylock(>sm_sem)) { + if (test_and_set_bit(UMAD_F_CLAIM, >flags)) { ret = -EAGAIN; goto fail; } } else { - if (down_interruptible(>sm_sem)) { + if (wait_event_interruptible(port->wq, +!test_and_set_bit(UMAD_F_CLAIM, +>flags))) { ret = -ERESTARTSYS; goto fail; } @@ -1060,7 +1065,8 @@ static int ib_umad_sm_open(struct inode *inode, struct file *filp) ib_modify_port(port->ib_dev, port->port_num, 0, ); err_up_sem: - up(>sm_sem); + clear_bit(UMAD_F_CLAIM, >flags); + wake_up(>wq); fail: return ret; @@ -1079,7 +1085,8 @@ static int ib_umad_sm_close(struct inode *inode, struct file *filp) ret = ib_modify_port(port->ib_dev, port->port_num, 0, ); mutex_unlock(>file_mutex); - up(>sm_sem); + clear_bit(UMAD_F_CLAIM, >flags); + wake_up(>wq); kobject_put(>umad_dev->kobj); @@ -1177,7 +1184,8 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, port->ib_dev = device; port->port_num = port_num; - sema_init(>sm_sem, 1); + init_waitqueue_head(>wq); + __clear_bit(UMAD_F_CLAIM, >flags); mutex_init(>file_mutex); INIT_LIST_HEAD(>file_list); -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 2/9] IB/core: Replace semaphore sm_sem with an atomic wait
The semaphore 'sm_sem' is used for an exclusive ownership of the device so model the same as an atomic variable with an associated wait_event. Semaphores are going away in the future. Signed-off-by: Binoy Jayan --- drivers/infiniband/core/user_mad.c | 20 ++-- 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 415a318..6101c0a 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -67,6 +67,8 @@ enum { IB_UMAD_MINOR_BASE = 0 }; +#define UMAD_F_CLAIM 0x01 + /* * Our lifetime rules for these structs are the following: * device special file is opened, we take a reference on the @@ -87,7 +89,8 @@ struct ib_umad_port { struct cdev sm_cdev; struct device *sm_dev; - struct semaphore sm_sem; + wait_queue_head_t wq; + unsigned long flags; struct mutex file_mutex; struct list_head file_list; @@ -1030,12 +1033,14 @@ static int ib_umad_sm_open(struct inode *inode, struct file *filp) port = container_of(inode->i_cdev, struct ib_umad_port, sm_cdev); if (filp->f_flags & O_NONBLOCK) { - if (down_trylock(>sm_sem)) { + if (test_and_set_bit(UMAD_F_CLAIM, >flags)) { ret = -EAGAIN; goto fail; } } else { - if (down_interruptible(>sm_sem)) { + if (wait_event_interruptible(port->wq, +!test_and_set_bit(UMAD_F_CLAIM, +>flags))) { ret = -ERESTARTSYS; goto fail; } @@ -1060,7 +1065,8 @@ static int ib_umad_sm_open(struct inode *inode, struct file *filp) ib_modify_port(port->ib_dev, port->port_num, 0, ); err_up_sem: - up(>sm_sem); + clear_bit(UMAD_F_CLAIM, >flags); + wake_up(>wq); fail: return ret; @@ -1079,7 +1085,8 @@ static int ib_umad_sm_close(struct inode *inode, struct file *filp) ret = ib_modify_port(port->ib_dev, port->port_num, 0, ); mutex_unlock(>file_mutex); - up(>sm_sem); + clear_bit(UMAD_F_CLAIM, >flags); + wake_up(>wq); kobject_put(>umad_dev->kobj); @@ -1177,7 +1184,8 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, port->ib_dev = device; port->port_num = port_num; - sema_init(>sm_sem, 1); + init_waitqueue_head(>wq); + __clear_bit(UMAD_F_CLAIM, >flags); mutex_init(>file_mutex); INIT_LIST_HEAD(>file_list); -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 5/9] IB/isert: Replace semaphore sem with completion
The semaphore 'sem' in isert_device is used as completion, but in a counting fashion as isert_connected_handler could be called multiple times during which it allows for that number of waiters (isert_accept_np) to continue without blocking, each consuming one node out from the list isert_np-pending in the same order in which they were enqueued (FIFO). So, convert it to struct completion. Semaphores are going away in the future. Signed-off-by: Binoy Jayan--- drivers/infiniband/ulp/isert/ib_isert.c | 6 +++--- drivers/infiniband/ulp/isert/ib_isert.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 6dd43f6..de80f56 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -619,7 +619,7 @@ mutex_unlock(_np->mutex); isert_info("np %p: Allow accept_np to continue\n", isert_np); - up(_np->sem); + complete(_np->comp); } static void @@ -2311,7 +2311,7 @@ struct rdma_cm_id * isert_err("Unable to allocate struct isert_np\n"); return -ENOMEM; } - sema_init(_np->sem, 0); + init_completion(_np->comp); mutex_init(_np->mutex); INIT_LIST_HEAD(_np->accepted); INIT_LIST_HEAD(_np->pending); @@ -2427,7 +2427,7 @@ struct rdma_cm_id * int ret; accept_wait: - ret = down_interruptible(_np->sem); + ret = wait_for_completion_interruptible(_np->comp); if (ret) return -ENODEV; diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index c02ada5..a1277c0 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -190,7 +191,7 @@ struct isert_device { struct isert_np { struct iscsi_np *np; - struct semaphoresem; + struct completion comp; struct rdma_cm_id *cm_id; struct mutexmutex; struct list_headaccepted; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 5/9] IB/isert: Replace semaphore sem with completion
The semaphore 'sem' in isert_device is used as completion, but in a counting fashion as isert_connected_handler could be called multiple times during which it allows for that number of waiters (isert_accept_np) to continue without blocking, each consuming one node out from the list isert_np-pending in the same order in which they were enqueued (FIFO). So, convert it to struct completion. Semaphores are going away in the future. Signed-off-by: Binoy Jayan --- drivers/infiniband/ulp/isert/ib_isert.c | 6 +++--- drivers/infiniband/ulp/isert/ib_isert.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 6dd43f6..de80f56 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -619,7 +619,7 @@ mutex_unlock(_np->mutex); isert_info("np %p: Allow accept_np to continue\n", isert_np); - up(_np->sem); + complete(_np->comp); } static void @@ -2311,7 +2311,7 @@ struct rdma_cm_id * isert_err("Unable to allocate struct isert_np\n"); return -ENOMEM; } - sema_init(_np->sem, 0); + init_completion(_np->comp); mutex_init(_np->mutex); INIT_LIST_HEAD(_np->accepted); INIT_LIST_HEAD(_np->pending); @@ -2427,7 +2427,7 @@ struct rdma_cm_id * int ret; accept_wait: - ret = down_interruptible(_np->sem); + ret = wait_for_completion_interruptible(_np->comp); if (ret) return -ENODEV; diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index c02ada5..a1277c0 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -190,7 +191,7 @@ struct isert_device { struct isert_np { struct iscsi_np *np; - struct semaphoresem; + struct completion comp; struct rdma_cm_id *cm_id; struct mutexmutex; struct list_headaccepted; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 4/9] IB/mthca: Replace semaphore poll_sem with mutex
The semaphore 'poll_sem' is a simple mutex, so it should be written as one. Semaphores are going away in the future. So replace it with a mutex. Also, remove mutex_[un]lock from mthca_cmd_use_events and mthca_cmd_use_polling respectively. Signed-off-by: Binoy Jayan--- drivers/infiniband/hw/mthca/mthca_cmd.c | 10 +++--- drivers/infiniband/hw/mthca/mthca_cmd.h | 1 + drivers/infiniband/hw/mthca/mthca_dev.h | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index c7f49bb..49c6e19 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -347,7 +347,7 @@ static int mthca_cmd_poll(struct mthca_dev *dev, unsigned long end; u8 status; - down(>cmd.poll_sem); + mutex_lock(>cmd.poll_mutex); err = mthca_cmd_post(dev, in_param, out_param ? *out_param : 0, @@ -382,7 +382,7 @@ static int mthca_cmd_poll(struct mthca_dev *dev, } out: - up(>cmd.poll_sem); + mutex_unlock(>cmd.poll_mutex); return err; } @@ -520,7 +520,7 @@ static int mthca_cmd_imm(struct mthca_dev *dev, int mthca_cmd_init(struct mthca_dev *dev) { mutex_init(>cmd.hcr_mutex); - sema_init(>cmd.poll_sem, 1); + mutex_init(>cmd.poll_mutex); dev->cmd.flags = 0; dev->hcr = ioremap(pci_resource_start(dev->pdev, 0) + MTHCA_HCR_BASE, @@ -582,8 +582,6 @@ int mthca_cmd_use_events(struct mthca_dev *dev) dev->cmd.flags |= MTHCA_CMD_USE_EVENTS; - down(>cmd.poll_sem); - return 0; } @@ -600,8 +598,6 @@ void mthca_cmd_use_polling(struct mthca_dev *dev) down(>cmd.event_sem); kfree(dev->cmd.context); - - up(>cmd.poll_sem); } struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev, diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h index d2e5b19..a7f197e 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.h +++ b/drivers/infiniband/hw/mthca/mthca_cmd.h @@ -35,6 +35,7 @@ #ifndef MTHCA_CMD_H #define MTHCA_CMD_H +#include #include #define MTHCA_MAILBOX_SIZE 4096 diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 4393a02..87ab964 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -120,7 +120,7 @@ enum { struct mthca_cmd { struct pci_pool *pool; struct mutex hcr_mutex; - struct semaphore poll_sem; + struct mutex poll_mutex; struct semaphore event_sem; int max_cmds; spinlock_tcontext_lock; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 4/9] IB/mthca: Replace semaphore poll_sem with mutex
The semaphore 'poll_sem' is a simple mutex, so it should be written as one. Semaphores are going away in the future. So replace it with a mutex. Also, remove mutex_[un]lock from mthca_cmd_use_events and mthca_cmd_use_polling respectively. Signed-off-by: Binoy Jayan --- drivers/infiniband/hw/mthca/mthca_cmd.c | 10 +++--- drivers/infiniband/hw/mthca/mthca_cmd.h | 1 + drivers/infiniband/hw/mthca/mthca_dev.h | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index c7f49bb..49c6e19 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -347,7 +347,7 @@ static int mthca_cmd_poll(struct mthca_dev *dev, unsigned long end; u8 status; - down(>cmd.poll_sem); + mutex_lock(>cmd.poll_mutex); err = mthca_cmd_post(dev, in_param, out_param ? *out_param : 0, @@ -382,7 +382,7 @@ static int mthca_cmd_poll(struct mthca_dev *dev, } out: - up(>cmd.poll_sem); + mutex_unlock(>cmd.poll_mutex); return err; } @@ -520,7 +520,7 @@ static int mthca_cmd_imm(struct mthca_dev *dev, int mthca_cmd_init(struct mthca_dev *dev) { mutex_init(>cmd.hcr_mutex); - sema_init(>cmd.poll_sem, 1); + mutex_init(>cmd.poll_mutex); dev->cmd.flags = 0; dev->hcr = ioremap(pci_resource_start(dev->pdev, 0) + MTHCA_HCR_BASE, @@ -582,8 +582,6 @@ int mthca_cmd_use_events(struct mthca_dev *dev) dev->cmd.flags |= MTHCA_CMD_USE_EVENTS; - down(>cmd.poll_sem); - return 0; } @@ -600,8 +598,6 @@ void mthca_cmd_use_polling(struct mthca_dev *dev) down(>cmd.event_sem); kfree(dev->cmd.context); - - up(>cmd.poll_sem); } struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev, diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h index d2e5b19..a7f197e 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.h +++ b/drivers/infiniband/hw/mthca/mthca_cmd.h @@ -35,6 +35,7 @@ #ifndef MTHCA_CMD_H #define MTHCA_CMD_H +#include #include #define MTHCA_MAILBOX_SIZE 4096 diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 4393a02..87ab964 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -120,7 +120,7 @@ enum { struct mthca_cmd { struct pci_pool *pool; struct mutex hcr_mutex; - struct semaphore poll_sem; + struct mutex poll_mutex; struct semaphore event_sem; int max_cmds; spinlock_tcontext_lock; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v2 2/6] powerpc/powernv: Autoload IMA device driver module
This patch does three things : - Enables "opal.c" to create a platform device for the IMA interface according to the appropriate compatibility string. - Find the reserved-memory region details from the system device tree and get the base address of HOMER region address for each chip. - We also get the Nest PMU counter data offsets (in the HOMER region) and their sizes. The offsets for the counters' data are fixed and won't change from chip to chip. The device tree parsing logic is separated from the PMU creation functions (which is done in subsequent patches). Right now, only Nest units are taken care of. Cc: Madhavan SrinivasanCc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- arch/powerpc/platforms/powernv/Makefile | 2 +- arch/powerpc/platforms/powernv/opal-ima.c | 117 ++ arch/powerpc/platforms/powernv/opal.c | 13 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/powernv/opal-ima.c diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index b5d98cb..ee28528 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -2,7 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o -obj-y += opal-kmsg.o +obj-y += opal-kmsg.o opal-ima.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o diff --git a/arch/powerpc/platforms/powernv/opal-ima.c b/arch/powerpc/platforms/powernv/opal-ima.c new file mode 100644 index 000..446e7bc --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-ima.c @@ -0,0 +1,117 @@ +/* + * OPAL IMA interface detection driver + * Supported on POWERNV platform + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + *(C) 2016 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; + +static int opal_ima_counters_probe(struct platform_device *pdev) +{ + struct device_node *child, *ima_dev, *rm_node = NULL; + struct perchip_nest_info *pcni; + u32 reg[4], pages, nest_offset, nest_size, idx; + int i = 0; + const char *node_name; + + if (!pdev || !pdev->dev.of_node) + return -ENODEV; + + ima_dev = pdev->dev.of_node; + + /* +* nest_offset : where the nest-counters' data start. +* size : size of the entire nest-counters region +*/ + if (of_property_read_u32(ima_dev, "ima-nest-offset", _offset)) + goto err; + if (of_property_read_u32(ima_dev, "ima-nest-size", _size)) + goto err; + + /* Find the "homer region" for each chip */ + rm_node = of_find_node_by_path("/reserved-memory"); + if (!rm_node) + goto err; + + for_each_child_of_node(rm_node, child) { + if (of_property_read_string_index(child, "name", 0, + _name)) + continue; + if (strncmp("ibm,homer-image", node_name, + strlen("ibm,homer-image"))) + continue; + + /* Get the chip id to which the above homer region belongs to */ + if (of_property_read_u32(child, "ibm,chip-id", )) + goto err; + + /* reg property will have four u32 cells. */ + if (of_property_read_u32_array(child, "reg", reg, 4)) + goto err; + + pcni = _perchip_info[idx]; + + /* Fetch the homer region base address */ +
Re: [PATCH 1/2] kbuild: provide include/asm/asm-prototypes.h for ARM
On Sun, 20 Nov 2016 19:12:57 + Russell King - ARM Linuxwrote: > On Sun, Nov 20, 2016 at 10:32:50AM -0800, Linus Torvalds wrote: > > On Sun, Nov 20, 2016 at 5:21 AM, Russell King - ARM Linux > > wrote: > > > On Tue, Oct 25, 2016 at 07:32:00PM +1100, Nicholas Piggin wrote: > > >> > > >> Michal, what's your thoughts? If you merge my patch 2/2 and skip 1/2, it > > >> should not give any new build warnings or errors, so then arch patches > > >> can > > >> go via arch trees. 1/2 could go in after everyone is up to date. > > > > > > So what's the conclusion on this? I've just had a failure due to > > > CONFIG_TRIM_UNUSED_KSYMS reported on ARM, and it looks like (at > > > least some of) patch 1 could resolve it. > > > > Hmm. I've got > > > > cc6acc11cad1 kbuild: be more careful about matching preprocessed asm > > ___EXPORT_SYMBOL > > 4efca4ed05cb kbuild: modversions for EXPORT_SYMBOL() for asm > > > > in my tree. Is that sufficient, or do we still have issues? > > Hmm, those seem to have gone in during the last week, so I haven't > tested it yet (build running, but it'll take a while). However, I > don't think they'll solve _this_ problem. > > Some of the issue here is that we use a mixture of assembly macros > and preprocessor for the ARM bitops - the ARM bitops are created > with an assembly macro which contains some pre-processor expanded > macros (eg, EXPORT_SYMBOL()). > > This means that the actual symbol being exported is not known to > the preprocessor, so doing the "__is_defined(__KSYM_##sym)" inside > "EXPORT_SYMBOL(\name)" becomes "__is_defined(__KSYM_\name)" to the > preprocessor. As "__KSYM_\name" is never defined, it always comes > out as zero, hence we always use __cond_export_sym_0, which omits > the symbol export from the assembly macro definition: > > .macro bitop, name, instr > .globl \name ; .align 0 ; \name: > > ... > > .type \name, %function; .size \name, .-\name > > .endm > > In other words, using preprocessor macros inside an assembly macro > may not work as expected, and now leads to config-specific failures. > Yes, that's a limitation. cpp expansion we can handle, but not gas macros. You will need Arnd's patches for ARM. http://marc.info/?l=linux-kbuild=147732160529499=2 If that doesn't fix it for you, send me your .config offline and I'll set up a cross compile to work on it. Again, any arch always has the option of going back to doing asm exports in the old style of putting them into a .c file, but hopefully you'll find Arnd's reworked patches to be something you're willing to merge. Thanks, Nick
Re: [PATCH v16 04/15] clocksource/drivers/arm_arch_timer: rename some enums and defines, and some cleanups.
Hi Mark, On 19 November 2016 at 02:49, Mark Rutlandwrote: > On Wed, Nov 16, 2016 at 09:48:57PM +0800, fu@linaro.org wrote: >> From: Fu Wei >> >> Rename some enums and defines, to unify the format of enums and defines >> in arm_arch_timer.h, also update all the users of these enums and defines: >> drivers/clocksource/arm_arch_timer.c >> virt/kvm/arm/hyp/timer-sr.c > > I'm happy with making definitions use a consistent ARCH_TIMER_ prefix, > given they're exposed in headers... > >> And do some cleanups, according to the suggestion from checkpatch.pl: >> (1) using BIT(nr) instead of (1 << nr) >> (2) using 'unsigned int' instead of 'unsigned' > > ... but these changes are pointless churn. They make the patch larger, > hardwer to review, and more painful to merge. > > Please leave these as they are unless there is a functional problem. If > there will be a functional problem unless these are changed, describe > that in the commit message. OK, Mark. I will take these out of patch, thanks :-) > > Thanks, > Mark. > >> >> No functional change. >> >> Signed-off-by: Fu Wei >> --- >> drivers/clocksource/arm_arch_timer.c | 111 >> ++- >> include/clocksource/arm_arch_timer.h | 40 ++--- >> virt/kvm/arm/hyp/timer-sr.c | 6 +- >> 3 files changed, 81 insertions(+), 76 deletions(-) >> >> diff --git a/drivers/clocksource/arm_arch_timer.c >> b/drivers/clocksource/arm_arch_timer.c >> index 15341cf..dd1040d 100644 >> --- a/drivers/clocksource/arm_arch_timer.c >> +++ b/drivers/clocksource/arm_arch_timer.c >> @@ -66,11 +66,11 @@ struct arch_timer { >> #define to_arch_timer(e) container_of(e, struct arch_timer, evt) >> >> static u32 arch_timer_rate; >> -static int arch_timer_ppi[MAX_TIMER_PPI]; >> +static int arch_timer_ppi[ARCH_TIMER_MAX_TIMER_PPI]; >> >> static struct clock_event_device __percpu *arch_timer_evt; >> >> -static enum arch_timer_ppi_nr arch_timer_uses_ppi = VIRT_PPI; >> +static enum arch_timer_ppi_nr arch_timer_uses_ppi = ARCH_TIMER_VIRT_PPI; >> static bool arch_timer_c3stop; >> static bool arch_timer_mem_use_virtual; >> >> @@ -340,7 +340,7 @@ static void fsl_a008585_set_sne(struct >> clock_event_device *clk) >> if (!static_branch_unlikely(_timer_read_ool_enabled)) >> return; >> >> - if (arch_timer_uses_ppi == VIRT_PPI) >> + if (arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) >> clk->set_next_event = fsl_a008585_set_next_event_virt; >> else >> clk->set_next_event = fsl_a008585_set_next_event_phys; >> @@ -352,7 +352,7 @@ static void __arch_timer_setup(unsigned type, >> { >> clk->features = CLOCK_EVT_FEAT_ONESHOT; >> >> - if (type == ARCH_CP15_TIMER) { >> + if (type == ARCH_TIMER_TYPE_CP15) { >> if (arch_timer_c3stop) >> clk->features |= CLOCK_EVT_FEAT_C3STOP; >> clk->name = "arch_sys_timer"; >> @@ -360,14 +360,14 @@ static void __arch_timer_setup(unsigned type, >> clk->cpumask = cpumask_of(smp_processor_id()); >> clk->irq = arch_timer_ppi[arch_timer_uses_ppi]; >> switch (arch_timer_uses_ppi) { >> - case VIRT_PPI: >> + case ARCH_TIMER_VIRT_PPI: >> clk->set_state_shutdown = arch_timer_shutdown_virt; >> clk->set_state_oneshot_stopped = >> arch_timer_shutdown_virt; >> clk->set_next_event = arch_timer_set_next_event_virt; >> break; >> - case PHYS_SECURE_PPI: >> - case PHYS_NONSECURE_PPI: >> - case HYP_PPI: >> + case ARCH_TIMER_PHYS_SECURE_PPI: >> + case ARCH_TIMER_PHYS_NONSECURE_PPI: >> + case ARCH_TIMER_HYP_PPI: >> clk->set_state_shutdown = arch_timer_shutdown_phys; >> clk->set_state_oneshot_stopped = >> arch_timer_shutdown_phys; >> clk->set_next_event = arch_timer_set_next_event_phys; >> @@ -447,8 +447,8 @@ static void arch_counter_set_user_access(void) >> >> static bool arch_timer_has_nonsecure_ppi(void) >> { >> - return (arch_timer_uses_ppi == PHYS_SECURE_PPI && >> - arch_timer_ppi[PHYS_NONSECURE_PPI]); >> + return (arch_timer_uses_ppi == ARCH_TIMER_PHYS_SECURE_PPI && >> + arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]); >> } >> >> static u32 check_ppi_trigger(int irq) >> @@ -469,14 +469,15 @@ static int arch_timer_starting_cpu(unsigned int cpu) >> struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt); >> u32 flags; >> >> - __arch_timer_setup(ARCH_CP15_TIMER, clk); >> + __arch_timer_setup(ARCH_TIMER_TYPE_CP15, clk); >> >> flags = check_ppi_trigger(arch_timer_ppi[arch_timer_uses_ppi]); >> enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags); >> >> if (arch_timer_has_nonsecure_ppi())
[PATCH v2 4/6] powerpc/perf: Add event attribute and group to IMA pmus
Device tree IMA driver code parses the IMA units and their events. It passes the information to IMA pmu code which is placed in powerpc/perf as "ima-pmu.c". This patch creates only event attributes and attribute groups for the IMA pmus. Cc: Madhavan SrinivasanCc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- Changelog: v1 -> v2: - Changes to Makefile to only enable this feature for CONFIG_PPC_POWERNV=y arch/powerpc/perf/Makefile| 6 +- arch/powerpc/perf/ima-pmu.c | 96 +++ arch/powerpc/platforms/powernv/opal-ima.c | 12 +++- 3 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 arch/powerpc/perf/ima-pmu.c diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index f102d53..099c61a 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -2,10 +2,14 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o +ima-$(CONFIG_PPC_POWERNV) += ima-pmu.o + obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ power5+-pmu.o power6-pmu.o power7-pmu.o \ - isa207-common.o power8-pmu.o power9-pmu.o + isa207-common.o power8-pmu.o power9-pmu.o \ + $(ima-y) + obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o diff --git a/arch/powerpc/perf/ima-pmu.c b/arch/powerpc/perf/ima-pmu.c new file mode 100644 index 000..50d2226 --- /dev/null +++ b/arch/powerpc/perf/ima-pmu.c @@ -0,0 +1,96 @@ +/* + * Nest Performance Monitor counter support. + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include + +struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; +struct ima_pmu *per_nest_pmu_arr[IMA_MAX_PMUS]; + +/* dev_str_attr : Populate event "name" and string "str" in attribute */ +static struct attribute *dev_str_attr(const char *name, const char *str) +{ + struct perf_pmu_events_attr *attr; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + + sysfs_attr_init(>attr.attr); + + attr->event_str = str; + attr->attr.attr.name = name; + attr->attr.attr.mode = 0444; + attr->attr.show = perf_event_sysfs_show; + + return >attr.attr; +} + +/* + * update_events_in_group: Update the "events" information in an attr_group + * and assign the attr_group to the pmu "pmu". + */ +static int update_events_in_group(struct ima_events *events, + int idx, struct ima_pmu *pmu) +{ + struct attribute_group *attr_group; + struct attribute **attrs; + int i; + + /* Allocate memory for attribute group */ + attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL); + if (!attr_group) + return -ENOMEM; + + /* Allocate memory for attributes */ + attrs = kzalloc((sizeof(struct attribute *) * (idx + 1)), GFP_KERNEL); + if (!attrs) { + kfree(attr_group); + return -ENOMEM; + } + + attr_group->name = "events"; + attr_group->attrs = attrs; + for (i = 0; i < idx; i++, events++) { + attrs[i] = dev_str_attr((char *)events->ev_name, + (char *)events->ev_value); + } + + pmu->attr_groups[0] = attr_group; + return 0; +} + +/* + * init_ima_pmu : Setup the IMA pmu device in "pmu_ptr" and its events + *"events". + * Setup the cpu mask information for these pmus and setup the state machine + * hotplug notifiers as well. + */ +int init_ima_pmu(struct ima_events *events, int idx, +struct ima_pmu *pmu_ptr) +{ + int ret = -ENODEV; + + ret = update_events_in_group(events, idx, pmu_ptr); + if (ret) + goto err_free; + + return 0; + +err_free: + /* Only free the attr_groups which are dynamically allocated */ + if (pmu_ptr->attr_groups[0]) { + kfree(pmu_ptr->attr_groups[0]->attrs); + kfree(pmu_ptr->attr_groups[0]); + } + + return ret; +} diff
[PATCH v2 2/6] powerpc/powernv: Autoload IMA device driver module
This patch does three things : - Enables "opal.c" to create a platform device for the IMA interface according to the appropriate compatibility string. - Find the reserved-memory region details from the system device tree and get the base address of HOMER region address for each chip. - We also get the Nest PMU counter data offsets (in the HOMER region) and their sizes. The offsets for the counters' data are fixed and won't change from chip to chip. The device tree parsing logic is separated from the PMU creation functions (which is done in subsequent patches). Right now, only Nest units are taken care of. Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- arch/powerpc/platforms/powernv/Makefile | 2 +- arch/powerpc/platforms/powernv/opal-ima.c | 117 ++ arch/powerpc/platforms/powernv/opal.c | 13 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/powernv/opal-ima.c diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index b5d98cb..ee28528 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -2,7 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o -obj-y += opal-kmsg.o +obj-y += opal-kmsg.o opal-ima.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o diff --git a/arch/powerpc/platforms/powernv/opal-ima.c b/arch/powerpc/platforms/powernv/opal-ima.c new file mode 100644 index 000..446e7bc --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-ima.c @@ -0,0 +1,117 @@ +/* + * OPAL IMA interface detection driver + * Supported on POWERNV platform + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + *(C) 2016 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; + +static int opal_ima_counters_probe(struct platform_device *pdev) +{ + struct device_node *child, *ima_dev, *rm_node = NULL; + struct perchip_nest_info *pcni; + u32 reg[4], pages, nest_offset, nest_size, idx; + int i = 0; + const char *node_name; + + if (!pdev || !pdev->dev.of_node) + return -ENODEV; + + ima_dev = pdev->dev.of_node; + + /* +* nest_offset : where the nest-counters' data start. +* size : size of the entire nest-counters region +*/ + if (of_property_read_u32(ima_dev, "ima-nest-offset", _offset)) + goto err; + if (of_property_read_u32(ima_dev, "ima-nest-size", _size)) + goto err; + + /* Find the "homer region" for each chip */ + rm_node = of_find_node_by_path("/reserved-memory"); + if (!rm_node) + goto err; + + for_each_child_of_node(rm_node, child) { + if (of_property_read_string_index(child, "name", 0, + _name)) + continue; + if (strncmp("ibm,homer-image", node_name, + strlen("ibm,homer-image"))) + continue; + + /* Get the chip id to which the above homer region belongs to */ + if (of_property_read_u32(child, "ibm,chip-id", )) + goto err; + + /* reg property will have four u32 cells. */ + if (of_property_read_u32_array(child, "reg", reg, 4)) + goto err; + + pcni = _perchip_info[idx]; + + /* Fetch the homer region base address */ + pcni->pbase = reg[0]; + pcni->pbase = pcni->pbase << 32 | reg[1]; + /* Add the nest IMA Base offset */ + pcni->pbase = pcni->pbase + nest_offset; + /* Fetch the size of the homer
Re: [PATCH 1/2] kbuild: provide include/asm/asm-prototypes.h for ARM
On Sun, 20 Nov 2016 19:12:57 + Russell King - ARM Linux wrote: > On Sun, Nov 20, 2016 at 10:32:50AM -0800, Linus Torvalds wrote: > > On Sun, Nov 20, 2016 at 5:21 AM, Russell King - ARM Linux > > wrote: > > > On Tue, Oct 25, 2016 at 07:32:00PM +1100, Nicholas Piggin wrote: > > >> > > >> Michal, what's your thoughts? If you merge my patch 2/2 and skip 1/2, it > > >> should not give any new build warnings or errors, so then arch patches > > >> can > > >> go via arch trees. 1/2 could go in after everyone is up to date. > > > > > > So what's the conclusion on this? I've just had a failure due to > > > CONFIG_TRIM_UNUSED_KSYMS reported on ARM, and it looks like (at > > > least some of) patch 1 could resolve it. > > > > Hmm. I've got > > > > cc6acc11cad1 kbuild: be more careful about matching preprocessed asm > > ___EXPORT_SYMBOL > > 4efca4ed05cb kbuild: modversions for EXPORT_SYMBOL() for asm > > > > in my tree. Is that sufficient, or do we still have issues? > > Hmm, those seem to have gone in during the last week, so I haven't > tested it yet (build running, but it'll take a while). However, I > don't think they'll solve _this_ problem. > > Some of the issue here is that we use a mixture of assembly macros > and preprocessor for the ARM bitops - the ARM bitops are created > with an assembly macro which contains some pre-processor expanded > macros (eg, EXPORT_SYMBOL()). > > This means that the actual symbol being exported is not known to > the preprocessor, so doing the "__is_defined(__KSYM_##sym)" inside > "EXPORT_SYMBOL(\name)" becomes "__is_defined(__KSYM_\name)" to the > preprocessor. As "__KSYM_\name" is never defined, it always comes > out as zero, hence we always use __cond_export_sym_0, which omits > the symbol export from the assembly macro definition: > > .macro bitop, name, instr > .globl \name ; .align 0 ; \name: > > ... > > .type \name, %function; .size \name, .-\name > > .endm > > In other words, using preprocessor macros inside an assembly macro > may not work as expected, and now leads to config-specific failures. > Yes, that's a limitation. cpp expansion we can handle, but not gas macros. You will need Arnd's patches for ARM. http://marc.info/?l=linux-kbuild=147732160529499=2 If that doesn't fix it for you, send me your .config offline and I'll set up a cross compile to work on it. Again, any arch always has the option of going back to doing asm exports in the old style of putting them into a .c file, but hopefully you'll find Arnd's reworked patches to be something you're willing to merge. Thanks, Nick
Re: [PATCH v16 04/15] clocksource/drivers/arm_arch_timer: rename some enums and defines, and some cleanups.
Hi Mark, On 19 November 2016 at 02:49, Mark Rutland wrote: > On Wed, Nov 16, 2016 at 09:48:57PM +0800, fu@linaro.org wrote: >> From: Fu Wei >> >> Rename some enums and defines, to unify the format of enums and defines >> in arm_arch_timer.h, also update all the users of these enums and defines: >> drivers/clocksource/arm_arch_timer.c >> virt/kvm/arm/hyp/timer-sr.c > > I'm happy with making definitions use a consistent ARCH_TIMER_ prefix, > given they're exposed in headers... > >> And do some cleanups, according to the suggestion from checkpatch.pl: >> (1) using BIT(nr) instead of (1 << nr) >> (2) using 'unsigned int' instead of 'unsigned' > > ... but these changes are pointless churn. They make the patch larger, > hardwer to review, and more painful to merge. > > Please leave these as they are unless there is a functional problem. If > there will be a functional problem unless these are changed, describe > that in the commit message. OK, Mark. I will take these out of patch, thanks :-) > > Thanks, > Mark. > >> >> No functional change. >> >> Signed-off-by: Fu Wei >> --- >> drivers/clocksource/arm_arch_timer.c | 111 >> ++- >> include/clocksource/arm_arch_timer.h | 40 ++--- >> virt/kvm/arm/hyp/timer-sr.c | 6 +- >> 3 files changed, 81 insertions(+), 76 deletions(-) >> >> diff --git a/drivers/clocksource/arm_arch_timer.c >> b/drivers/clocksource/arm_arch_timer.c >> index 15341cf..dd1040d 100644 >> --- a/drivers/clocksource/arm_arch_timer.c >> +++ b/drivers/clocksource/arm_arch_timer.c >> @@ -66,11 +66,11 @@ struct arch_timer { >> #define to_arch_timer(e) container_of(e, struct arch_timer, evt) >> >> static u32 arch_timer_rate; >> -static int arch_timer_ppi[MAX_TIMER_PPI]; >> +static int arch_timer_ppi[ARCH_TIMER_MAX_TIMER_PPI]; >> >> static struct clock_event_device __percpu *arch_timer_evt; >> >> -static enum arch_timer_ppi_nr arch_timer_uses_ppi = VIRT_PPI; >> +static enum arch_timer_ppi_nr arch_timer_uses_ppi = ARCH_TIMER_VIRT_PPI; >> static bool arch_timer_c3stop; >> static bool arch_timer_mem_use_virtual; >> >> @@ -340,7 +340,7 @@ static void fsl_a008585_set_sne(struct >> clock_event_device *clk) >> if (!static_branch_unlikely(_timer_read_ool_enabled)) >> return; >> >> - if (arch_timer_uses_ppi == VIRT_PPI) >> + if (arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) >> clk->set_next_event = fsl_a008585_set_next_event_virt; >> else >> clk->set_next_event = fsl_a008585_set_next_event_phys; >> @@ -352,7 +352,7 @@ static void __arch_timer_setup(unsigned type, >> { >> clk->features = CLOCK_EVT_FEAT_ONESHOT; >> >> - if (type == ARCH_CP15_TIMER) { >> + if (type == ARCH_TIMER_TYPE_CP15) { >> if (arch_timer_c3stop) >> clk->features |= CLOCK_EVT_FEAT_C3STOP; >> clk->name = "arch_sys_timer"; >> @@ -360,14 +360,14 @@ static void __arch_timer_setup(unsigned type, >> clk->cpumask = cpumask_of(smp_processor_id()); >> clk->irq = arch_timer_ppi[arch_timer_uses_ppi]; >> switch (arch_timer_uses_ppi) { >> - case VIRT_PPI: >> + case ARCH_TIMER_VIRT_PPI: >> clk->set_state_shutdown = arch_timer_shutdown_virt; >> clk->set_state_oneshot_stopped = >> arch_timer_shutdown_virt; >> clk->set_next_event = arch_timer_set_next_event_virt; >> break; >> - case PHYS_SECURE_PPI: >> - case PHYS_NONSECURE_PPI: >> - case HYP_PPI: >> + case ARCH_TIMER_PHYS_SECURE_PPI: >> + case ARCH_TIMER_PHYS_NONSECURE_PPI: >> + case ARCH_TIMER_HYP_PPI: >> clk->set_state_shutdown = arch_timer_shutdown_phys; >> clk->set_state_oneshot_stopped = >> arch_timer_shutdown_phys; >> clk->set_next_event = arch_timer_set_next_event_phys; >> @@ -447,8 +447,8 @@ static void arch_counter_set_user_access(void) >> >> static bool arch_timer_has_nonsecure_ppi(void) >> { >> - return (arch_timer_uses_ppi == PHYS_SECURE_PPI && >> - arch_timer_ppi[PHYS_NONSECURE_PPI]); >> + return (arch_timer_uses_ppi == ARCH_TIMER_PHYS_SECURE_PPI && >> + arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]); >> } >> >> static u32 check_ppi_trigger(int irq) >> @@ -469,14 +469,15 @@ static int arch_timer_starting_cpu(unsigned int cpu) >> struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt); >> u32 flags; >> >> - __arch_timer_setup(ARCH_CP15_TIMER, clk); >> + __arch_timer_setup(ARCH_TIMER_TYPE_CP15, clk); >> >> flags = check_ppi_trigger(arch_timer_ppi[arch_timer_uses_ppi]); >> enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags); >> >> if (arch_timer_has_nonsecure_ppi()) { >> - flags =
[PATCH v2 4/6] powerpc/perf: Add event attribute and group to IMA pmus
Device tree IMA driver code parses the IMA units and their events. It passes the information to IMA pmu code which is placed in powerpc/perf as "ima-pmu.c". This patch creates only event attributes and attribute groups for the IMA pmus. Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- Changelog: v1 -> v2: - Changes to Makefile to only enable this feature for CONFIG_PPC_POWERNV=y arch/powerpc/perf/Makefile| 6 +- arch/powerpc/perf/ima-pmu.c | 96 +++ arch/powerpc/platforms/powernv/opal-ima.c | 12 +++- 3 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 arch/powerpc/perf/ima-pmu.c diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index f102d53..099c61a 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -2,10 +2,14 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o +ima-$(CONFIG_PPC_POWERNV) += ima-pmu.o + obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ power5+-pmu.o power6-pmu.o power7-pmu.o \ - isa207-common.o power8-pmu.o power9-pmu.o + isa207-common.o power8-pmu.o power9-pmu.o \ + $(ima-y) + obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o diff --git a/arch/powerpc/perf/ima-pmu.c b/arch/powerpc/perf/ima-pmu.c new file mode 100644 index 000..50d2226 --- /dev/null +++ b/arch/powerpc/perf/ima-pmu.c @@ -0,0 +1,96 @@ +/* + * Nest Performance Monitor counter support. + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include + +struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; +struct ima_pmu *per_nest_pmu_arr[IMA_MAX_PMUS]; + +/* dev_str_attr : Populate event "name" and string "str" in attribute */ +static struct attribute *dev_str_attr(const char *name, const char *str) +{ + struct perf_pmu_events_attr *attr; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + + sysfs_attr_init(>attr.attr); + + attr->event_str = str; + attr->attr.attr.name = name; + attr->attr.attr.mode = 0444; + attr->attr.show = perf_event_sysfs_show; + + return >attr.attr; +} + +/* + * update_events_in_group: Update the "events" information in an attr_group + * and assign the attr_group to the pmu "pmu". + */ +static int update_events_in_group(struct ima_events *events, + int idx, struct ima_pmu *pmu) +{ + struct attribute_group *attr_group; + struct attribute **attrs; + int i; + + /* Allocate memory for attribute group */ + attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL); + if (!attr_group) + return -ENOMEM; + + /* Allocate memory for attributes */ + attrs = kzalloc((sizeof(struct attribute *) * (idx + 1)), GFP_KERNEL); + if (!attrs) { + kfree(attr_group); + return -ENOMEM; + } + + attr_group->name = "events"; + attr_group->attrs = attrs; + for (i = 0; i < idx; i++, events++) { + attrs[i] = dev_str_attr((char *)events->ev_name, + (char *)events->ev_value); + } + + pmu->attr_groups[0] = attr_group; + return 0; +} + +/* + * init_ima_pmu : Setup the IMA pmu device in "pmu_ptr" and its events + *"events". + * Setup the cpu mask information for these pmus and setup the state machine + * hotplug notifiers as well. + */ +int init_ima_pmu(struct ima_events *events, int idx, +struct ima_pmu *pmu_ptr) +{ + int ret = -ENODEV; + + ret = update_events_in_group(events, idx, pmu_ptr); + if (ret) + goto err_free; + + return 0; + +err_free: + /* Only free the attr_groups which are dynamically allocated */ + if (pmu_ptr->attr_groups[0]) { + kfree(pmu_ptr->attr_groups[0]->attrs); + kfree(pmu_ptr->attr_groups[0]); + } + + return ret; +} diff --git a/arch/powerpc/platforms/powernv/opal-ima.c b/arch/powerpc/platforms/powernv/opal-ima.c index e8d5771..d2e6910 100644 --- a/arch/powerpc/platforms/powernv/opal-ima.c +++ b/arch/powerpc/platforms/powernv/opal-ima.c @@ -31,8
[PATCH v2 0/6] IMA Instrumentation Support
Power 9 has In-Memory-Accumulation (IMA) infrastructure which contains various Performance Monitoring Units (PMUs) at Nest level (these are on-chip but off-core). These Nest PMU counters are handled by a Nest IMA microcode. This microcode runs in the OCC (On-Chip Controller) complex and its purpose is to program the nest counters, collect the counter data and move the counter data to memory. The IMA infrastructure encapsulates nest (per-chip), core and thread level counters. While the nest IMA PMUs are handled by the nest IMA microcode, the core and thread level PMUs are handled by the Core-HPMC engine. This patchset enables the nest IMA PMUs and is based on the initial work done by Madhavan Srinivasan. "Nest Instrumentation Support" : https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-August/132078.html v1 for this patchset can be found here : https://lwn.net/Articles/705475/ Nest events: Per-chip nest instrumentation provides various per-chip metrics such as memory, powerbus, Xlink and Alink bandwidth. PMU Events' Information: OPAL obtains the Nest PMU and event information from the IMA Catalog and passes on to the kernel via the device tree. The events' information contains : - Event name - Event Offset - Event description and, maybe : - Event scale - Event unit Some PMUs may have a common scale and unit values for all their supported events. For those cases, the scale and unit properties for those events must be inherited from the PMU. The event offset in the memory is where the counter data gets accumulated. The OPAL-side patches are posted upstream : https://lists.ozlabs.org/pipermail/skiboot/2016-November/005552.html The kernel discovers the IMA counters information in the device tree at the "ima-counters" device node which has a compatible field "ibm,opal-in-memory-counters". Parsing of the Events' information: To parse the IMA PMUs and events information, the kernel has to discover the "ima-counters" node and walk through the pmu and event nodes. Here is an excerpt of the dt showing the ima-counters and mcs node: /dts-v1/; [...] ima-counters { ima-nest-offset = <0x32>; compatible = "ibm,opal-in-memory-counters"; ima-nest-size = <0x3>; #address-cells = <0x1>; #size-cells = <0x1>; phandle = <0x1238>; version-id = [00]; mcs0 { compatible = "ibm,ima-counters-chip"; ranges; #address-cells = <0x1>; #size-cells = <0x1>; phandle = <0x1279>; scale = "1.2207e-4"; unit = "MiB"; event@528 { event-name = "PM_MCS_UP_128B_DATA_XFER_MC0" ; desc = "Total Read Bandwidth seen on both MCS of MC0"; phandle = <0x128c>; reg = <0x118 0x8>; }; [...] >From the device tree, the kernel parses the PMUs and their events' information. After parsing the nest IMA PMUs and their events, the PMUs and their attributes are registered in the kernel. Example Usage : # perf list [...] nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0/ [Kernel PMU event] nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0_LAST_SAMPLE/ [Kernel PMU event] [...] # perf stat -e "nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0/" -a --per-socket TODOs: - Add support for Core IMA. - Add support for thread IMA. Comments/feedback/suggestions are welcome. Changelog: v1 -> v2 : - Account for the cases where a PMU can have a common scale and unit values for all its supported events (Patch 3/6). - Fixed a Build error (for maple_defconfig) by enabling ima_pmu.o only for CONFIG_PPC_POWERNV=y (Patch 4/6) - Read from the "event-name" property instead of "name" for an event node (Patch 3/6). Cc: Madhavan SrinivasanCc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Daniel Axtens Cc: Stephane Eranian Signed-off-by: Hemant Kumar Hemant Kumar (6): powerpc/powernv: Data structure and macros definitions powerpc/powernv: Autoload IMA device driver module powerpc/powernv: Detect supported IMA units and its events powerpc/perf: Add event attribute and group to IMA pmus powerpc/perf: Generic ima pmu event functions powerpc/perf: IMA pmu cpumask and cpu hotplug support
[PATCH v5 6/9] IB/hns: Replace counting semaphore event_sem with wait_event
Counting semaphores are going away in the future, so replace the semaphore mthca_cmd::event_sem with a conditional wait_event. Signed-off-by: Binoy Jayan--- drivers/infiniband/hw/hns/hns_roce_cmd.c| 46 - drivers/infiniband/hw/hns/hns_roce_device.h | 2 +- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c index 51a0675..12ef3d8 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cmd.c +++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c @@ -189,6 +189,34 @@ void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status, complete(>done); } +static inline struct hns_roce_cmd_context * +hns_roce_try_get_context(struct hns_roce_cmdq *cmd) +{ + struct hns_roce_cmd_context *context = NULL; + + spin_lock(>context_lock); + + if (cmd->free_head < 0) + goto out; + + context = >context[cmd->free_head]; + context->token += cmd->token_mask + 1; + cmd->free_head = context->next; +out: + spin_unlock(>context_lock); + return context; +} + +/* wait for and acquire a free context */ +static inline struct hns_roce_cmd_context * +hns_roce_get_free_context(struct hns_roce_cmdq *cmd) +{ + struct hns_roce_cmd_context *context; + + wait_event(cmd->wq, (context = hns_roce_try_get_context(cmd))); + return context; +} + /* this should be called with "use_events" */ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param, unsigned long in_modifier, @@ -200,13 +228,7 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, struct hns_roce_cmd_context *context; int ret = 0; - spin_lock(>context_lock); - WARN_ON(cmd->free_head < 0); - context = >context[cmd->free_head]; - context->token += cmd->token_mask + 1; - cmd->free_head = context->next; - spin_unlock(>context_lock); - + context = hns_roce_get_free_context(cmd); init_completion(>done); ret = hns_roce_cmd_mbox_post_hw(hr_dev, in_param, out_param, @@ -238,6 +260,7 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, context->next = cmd->free_head; cmd->free_head = context - cmd->context; spin_unlock(>context_lock); + wake_up(>wq); return ret; } @@ -248,10 +271,8 @@ static int hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, { int ret = 0; - down(_dev->cmd.event_sem); ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param, in_modifier, op_modifier, op, timeout); - up(_dev->cmd.event_sem); return ret; } @@ -313,7 +334,7 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev) hr_cmd->context[hr_cmd->max_cmds - 1].next = -1; hr_cmd->free_head = 0; - sema_init(_cmd->event_sem, hr_cmd->max_cmds); + init_waitqueue_head(_cmd->wq); spin_lock_init(_cmd->context_lock); hr_cmd->token_mask = CMD_TOKEN_MASK; @@ -325,12 +346,9 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev) void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev) { struct hns_roce_cmdq *hr_cmd = _dev->cmd; - int i; hr_cmd->use_events = 0; - - for (i = 0; i < hr_cmd->max_cmds; ++i) - down(_cmd->event_sem); + hr_cmd->free_head = -1; kfree(hr_cmd->context); } diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 2afe075..ac95f52 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -364,7 +364,7 @@ struct hns_roce_cmdq { * Event mode: cmd register mutex protection, * ensure to not exceed max_cmds and user use limit region */ - struct semaphoreevent_sem; + wait_queue_head_t wq; int max_cmds; spinlock_t context_lock; int free_head; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 7/9] IB/mthca: Replace counting semaphore event_sem with wait_event
Counting semaphores are going away in the future, so replace the semaphore mthca_cmd::event_sem with a conditional wait_event. Signed-off-by: Binoy Jayan--- drivers/infiniband/hw/mthca/mthca_cmd.c | 47 ++--- drivers/infiniband/hw/mthca/mthca_dev.h | 3 ++- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 49c6e19..d6a048a 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -405,6 +405,34 @@ void mthca_cmd_event(struct mthca_dev *dev, complete(>done); } +static inline struct mthca_cmd_context * +mthca_try_get_context(struct mthca_cmd *cmd) +{ + struct mthca_cmd_context *context = NULL; + + spin_lock(>context_lock); + + if (cmd->free_head < 0) + goto out; + + context = >context[cmd->free_head]; + context->token += cmd->token_mask + 1; + cmd->free_head = context->next; +out: + spin_unlock(>context_lock); + return context; +} + +/* wait for and acquire a free context */ +static inline struct mthca_cmd_context * +mthca_get_free_context(struct mthca_cmd *cmd) +{ + struct mthca_cmd_context *context; + + wait_event(cmd->wq, (context = mthca_try_get_context(cmd))); + return context; +} + static int mthca_cmd_wait(struct mthca_dev *dev, u64 in_param, u64 *out_param, @@ -417,15 +445,7 @@ static int mthca_cmd_wait(struct mthca_dev *dev, int err = 0; struct mthca_cmd_context *context; - down(>cmd.event_sem); - - spin_lock(>cmd.context_lock); - BUG_ON(dev->cmd.free_head < 0); - context = >cmd.context[dev->cmd.free_head]; - context->token += dev->cmd.token_mask + 1; - dev->cmd.free_head = context->next; - spin_unlock(>cmd.context_lock); - + context = mthca_get_free_context(>cmd); init_completion(>done); err = mthca_cmd_post(dev, in_param, @@ -458,8 +478,8 @@ static int mthca_cmd_wait(struct mthca_dev *dev, context->next = dev->cmd.free_head; dev->cmd.free_head = context - dev->cmd.context; spin_unlock(>cmd.context_lock); + wake_up(>cmd.wq); - up(>cmd.event_sem); return err; } @@ -571,7 +591,7 @@ int mthca_cmd_use_events(struct mthca_dev *dev) dev->cmd.context[dev->cmd.max_cmds - 1].next = -1; dev->cmd.free_head = 0; - sema_init(>cmd.event_sem, dev->cmd.max_cmds); + init_waitqueue_head(>cmd.wq); spin_lock_init(>cmd.context_lock); for (dev->cmd.token_mask = 1; @@ -590,12 +610,9 @@ int mthca_cmd_use_events(struct mthca_dev *dev) */ void mthca_cmd_use_polling(struct mthca_dev *dev) { - int i; - dev->cmd.flags &= ~MTHCA_CMD_USE_EVENTS; - for (i = 0; i < dev->cmd.max_cmds; ++i) - down(>cmd.event_sem); + dev->cmd.free_head = -1; kfree(dev->cmd.context); } diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 87ab964..2fc86db 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -46,6 +46,7 @@ #include #include +#include #include "mthca_provider.h" #include "mthca_doorbell.h" @@ -121,7 +122,7 @@ struct mthca_cmd { struct pci_pool *pool; struct mutex hcr_mutex; struct mutex poll_mutex; - struct semaphore event_sem; + wait_queue_head_t wq; int max_cmds; spinlock_tcontext_lock; int free_head; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 8/9] IB/mlx5: Add helper mlx5_ib_post_send_wait
Clean up the following common code (to post a list of work requests to the send queue of the specified QP) at various places and add a helper function 'mlx5_ib_post_send_wait' to implement the same. - Initialize 'mlx5_ib_umr_context' on stack - Assign "mlx5_umr_wr:wr:wr_cqe to umr_context.cqe - Acquire the semaphore - call ib_post_send with a single ib_send_wr - wait_for_completion() - Check for umr_context.status - Release the semaphore As semaphores are going away in the future, moving all of these into the shared helper leaves only a single function using the semaphore, which can then be rewritten to use something else. Signed-off-by: Binoy Jayan--- drivers/infiniband/hw/mlx5/mr.c | 115 +++- 1 file changed, 32 insertions(+), 83 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index d4ad672..1593856 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -856,16 +856,40 @@ static inline void mlx5_ib_init_umr_context(struct mlx5_ib_umr_context *context) init_completion(>done); } +static inline int mlx5_ib_post_send_wait(struct mlx5_ib_dev *dev, +struct mlx5_umr_wr *umrwr) +{ + struct umr_common *umrc = >umrc; + struct ib_send_wr *bad; + int err; + struct mlx5_ib_umr_context umr_context; + + mlx5_ib_init_umr_context(_context); + umrwr->wr.wr_cqe = _context.cqe; + + down(>sem); + err = ib_post_send(umrc->qp, >wr, ); + if (err) { + mlx5_ib_warn(dev, "UMR post send failed, err %d\n", err); + } else { + wait_for_completion(_context.done); + if (umr_context.status != IB_WC_SUCCESS) { + mlx5_ib_warn(dev, "reg umr failed (%u)\n", +umr_context.status); + err = -EFAULT; + } + } + up(>sem); + return err; +} + static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, u64 virt_addr, u64 len, int npages, int page_shift, int order, int access_flags) { struct mlx5_ib_dev *dev = to_mdev(pd->device); struct device *ddev = dev->ib_dev.dma_device; - struct umr_common *umrc = >umrc; - struct mlx5_ib_umr_context umr_context; struct mlx5_umr_wr umrwr = {}; - struct ib_send_wr *bad; struct mlx5_ib_mr *mr; struct ib_sge sg; int size; @@ -894,24 +918,12 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, if (err) goto free_mr; - mlx5_ib_init_umr_context(_context); - - umrwr.wr.wr_cqe = _context.cqe; prep_umr_reg_wqe(pd, , , dma, npages, mr->mmkey.key, page_shift, virt_addr, len, access_flags); - down(>sem); - err = ib_post_send(umrc->qp, , ); - if (err) { - mlx5_ib_warn(dev, "post send failed, err %d\n", err); + err = mlx5_ib_post_send_wait(dev, ); + if (err && err != -EFAULT) goto unmap_dma; - } else { - wait_for_completion(_context.done); - if (umr_context.status != IB_WC_SUCCESS) { - mlx5_ib_warn(dev, "reg umr failed\n"); - err = -EFAULT; - } - } mr->mmkey.iova = virt_addr; mr->mmkey.size = len; @@ -920,7 +932,6 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, mr->live = 1; unmap_dma: - up(>sem); dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE); kfree(mr_pas); @@ -940,13 +951,10 @@ int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, int npages, { struct mlx5_ib_dev *dev = mr->dev; struct device *ddev = dev->ib_dev.dma_device; - struct umr_common *umrc = >umrc; - struct mlx5_ib_umr_context umr_context; struct ib_umem *umem = mr->umem; int size; __be64 *pas; dma_addr_t dma; - struct ib_send_wr *bad; struct mlx5_umr_wr wr; struct ib_sge sg; int err = 0; @@ -1011,10 +1019,7 @@ int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, int npages, dma_sync_single_for_device(ddev, dma, size, DMA_TO_DEVICE); - mlx5_ib_init_umr_context(_context); - memset(, 0, sizeof(wr)); - wr.wr.wr_cqe = _context.cqe; sg.addr = dma; sg.length = ALIGN(npages * sizeof(u64), @@ -1031,19 +1036,7 @@ int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, int npages, wr.mkey = mr->mmkey.key; wr.target.offset = start_page_index; - down(>sem); - err = ib_post_send(umrc->qp, , ); -
[PATCH v2 5/6] powerpc/perf: Generic ima pmu event functions
Since, the IMA counters' data are periodically fed to a memory location, the functions to read/update, start/stop, add/del can be generic and can be used by all IMA PMU units. This patch adds a set of generic ima pmu related event functions to be used by each ima pmu unit. Add code to setup format attribute and to register ima pmus. Add a event_init function for nest_ima events. Cc: Madhavan SrinivasanCc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- arch/powerpc/include/asm/ima-pmu.h| 2 + arch/powerpc/perf/ima-pmu.c | 122 ++ arch/powerpc/platforms/powernv/opal-ima.c | 37 +++-- 3 files changed, 154 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/ima-pmu.h b/arch/powerpc/include/asm/ima-pmu.h index 0ed8886..f0d95bb 100644 --- a/arch/powerpc/include/asm/ima-pmu.h +++ b/arch/powerpc/include/asm/ima-pmu.h @@ -70,4 +70,6 @@ struct ima_pmu { #define UNKNOWN_DOMAIN -1 +int ima_get_domain(struct device_node *pmu_dev); + #endif /* PPC_POWERNV_IMA_PMU_DEF_H */ diff --git a/arch/powerpc/perf/ima-pmu.c b/arch/powerpc/perf/ima-pmu.c index 50d2226..9948636 100644 --- a/arch/powerpc/perf/ima-pmu.c +++ b/arch/powerpc/perf/ima-pmu.c @@ -17,6 +17,117 @@ struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; struct ima_pmu *per_nest_pmu_arr[IMA_MAX_PMUS]; +/* Needed for sanity check */ +extern u64 nest_max_offset; + +PMU_FORMAT_ATTR(event, "config:0-20"); +static struct attribute *ima_format_attrs[] = { + _attr_event.attr, + NULL, +}; + +static struct attribute_group ima_format_group = { + .name = "format", + .attrs = ima_format_attrs, +}; + +static int nest_ima_event_init(struct perf_event *event) +{ + int chip_id; + u32 config = event->attr.config; + struct perchip_nest_info *pcni; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + /* Sanity check for config (event offset) */ + if (config > nest_max_offset) + return -EINVAL; + + chip_id = topology_physical_package_id(event->cpu); + pcni = _perchip_info[chip_id]; + event->hw.event_base = pcni->vbase[config/PAGE_SIZE] + + (config & ~PAGE_MASK); + + return 0; +} + +static void ima_read_counter(struct perf_event *event) +{ + u64 *addr, data; + + addr = (u64 *)event->hw.event_base; + data = __be64_to_cpu(*addr); + local64_set(>hw.prev_count, data); +} + +static void ima_perf_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count, *addr; + + addr = (u64 *)event->hw.event_base; + counter_prev = local64_read(>hw.prev_count); + counter_new = __be64_to_cpu(*addr); + final_count = counter_new - counter_prev; + + local64_set(>hw.prev_count, counter_new); + local64_add(final_count, >count); +} + +static void ima_event_start(struct perf_event *event, int flags) +{ + ima_read_counter(event); +} + +static void ima_event_stop(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_UPDATE) + ima_perf_event_update(event); +} + +static int ima_event_add(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_START) + ima_event_start(event, flags); + + return 0; +} + +/* update_pmu_ops : Populate the appropriate operations for "pmu" */ +static int update_pmu_ops(struct ima_pmu *pmu) +{ + if (!pmu) + return -EINVAL; + + pmu->pmu.task_ctx_nr = perf_invalid_context; + pmu->pmu.event_init = nest_ima_event_init; + pmu->pmu.add = ima_event_add; + pmu->pmu.del = ima_event_stop; + pmu->pmu.start = ima_event_start; + pmu->pmu.stop = ima_event_stop; + pmu->pmu.read = ima_perf_event_update; + pmu->attr_groups[1] = _format_group; + pmu->pmu.attr_groups = pmu->attr_groups; + + return 0; +} + /* dev_str_attr : Populate event "name" and string "str" in attribute */ static struct attribute *dev_str_attr(const
[PATCH v2 3/6] powerpc/powernv: Detect supported IMA units and its events
Parse device tree to detect IMA units. Traverse through each IMA unit node to find supported events and corresponding unit/scale files (if any). Right now, only nest IMA units are supported. The nest IMA unit event node from device tree will contain the offset in the reserved memory region to get the counter data for a given event. The offsets for the nest events are contained in the "reg" property of the event "node". Kernel code uses this offset as event configuration value. Device tree parser code also looks for scale/unit property in the event node and passes on the value as an event attr for perf interface to use in the post processing by the perf tool. Some PMUs may have common scale and unit properties which implies that all events supported by this PMU inherit the scale and unit properties of the PMU itself. For those events, we need to set the common unit and scale values. For failure to initialize any unit or any event, disable that unit and continue setting up the rest of them. Cc: Madhavan SrinivasanCc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- Changelog : v1 -> v2: - Read from the "event-name" property instead of "name" property for an event node. - Assign scale and unit values for events for a PMU which has a common unit and scale value. arch/powerpc/platforms/powernv/opal-ima.c | 332 ++ 1 file changed, 332 insertions(+) diff --git a/arch/powerpc/platforms/powernv/opal-ima.c b/arch/powerpc/platforms/powernv/opal-ima.c index 446e7bc..e8d5771 100644 --- a/arch/powerpc/platforms/powernv/opal-ima.c +++ b/arch/powerpc/platforms/powernv/opal-ima.c @@ -32,6 +32,337 @@ #include struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; +struct ima_pmu *per_nest_pmu_arr[IMA_MAX_PMUS]; + +static int ima_event_info(char *name, struct ima_events *events) +{ + char *buf; + + /* memory for content */ + buf = kzalloc(IMA_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + events->ev_name = name; + events->ev_value = buf; + return 0; +} + +static int ima_event_info_str(struct property *pp, char *name, + struct ima_events *events) +{ + int ret; + + ret = ima_event_info(name, events); + if (ret) + return ret; + + if (!pp->value || (strnlen(pp->value, pp->length) == pp->length) || + (pp->length > IMA_MAX_PMU_NAME_LEN)) + return -EINVAL; + strncpy(events->ev_value, (const char *)pp->value, pp->length); + + return 0; +} + +static int ima_event_info_val(char *name, u32 val, + struct ima_events *events) +{ + int ret; + + ret = ima_event_info(name, events); + if (ret) + return ret; + sprintf(events->ev_value, "event=0x%x", val); + + return 0; +} + +static int set_event_property(struct property *pp, char *event_prop, + struct ima_events *events, char *ev_name) +{ + char *buf; + int ret; + + buf = kzalloc(IMA_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + sprintf(buf, "%s.%s", ev_name, event_prop); + ret = ima_event_info_str(pp, buf, events); + if (ret) { + kfree(events->ev_name); + kfree(events->ev_value); + } + + return ret; +} + +/* + * ima_events_node_parser: Parse the event node "dev" and assign the parsed + * information to event "events". + * + * Parses the "reg" property of this event. "reg" gives us the event offset. + * Also, parse the "scale" and "unit" properties, if any. + */ +static int ima_events_node_parser(struct device_node *dev, + struct ima_events *events, + struct property *event_scale, + struct property *event_unit) +{ + struct property *name, *pp; + char *ev_name; + u32 val; + int idx = 0, ret; + + if (!dev) + return -EINVAL; + + /* +* Loop through each property of an event node +*/ + name = of_find_property(dev, "event-name", NULL); + if (!name) + return -ENODEV; + + if (!name->value || + (strnlen(name->value, name->length) == name->length) || + (name->length > IMA_MAX_PMU_NAME_LEN)) + return -EINVAL; + + ev_name = kzalloc(IMA_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!ev_name) + return -ENOMEM; + +
[PATCH v2 1/6] powerpc/powernv: Data structure and macros definitions
Create new header file "ima-pmu.h" to add the data structures and macros needed for IMA pmu support. Cc: Madhavan SrinivasanCc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- arch/powerpc/include/asm/ima-pmu.h | 73 ++ 1 file changed, 73 insertions(+) create mode 100644 arch/powerpc/include/asm/ima-pmu.h diff --git a/arch/powerpc/include/asm/ima-pmu.h b/arch/powerpc/include/asm/ima-pmu.h new file mode 100644 index 000..0ed8886 --- /dev/null +++ b/arch/powerpc/include/asm/ima-pmu.h @@ -0,0 +1,73 @@ +#ifndef PPC_POWERNV_IMA_PMU_DEF_H +#define PPC_POWERNV_IMA_PMU_DEF_H + +/* + * Nest Performance Monitor counter support. + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define IMA_MAX_CHIPS 32 +#define IMA_MAX_PMUS 32 +#define IMA_MAX_PMU_NAME_LEN 256 + +#define NEST_IMA_ENGINE_START 1 +#define NEST_IMA_ENGINE_STOP 0 +#define NEST_MAX_PAGES 16 + +#define NEST_IMA_PRODUCTION_MODE 1 + +#define IMA_DTB_COMPAT "ibm,opal-in-memory-counters" +#define IMA_DTB_NEST_COMPAT"ibm,ima-counters-chip" + +/* + * Structure to hold per chip specific memory address + * information for nest pmus. Nest Counter data are exported + * in per-chip reserved memory region by the PORE Engine. + */ +struct perchip_nest_info { + u32 chip_id; + u64 pbase; + u64 vbase[NEST_MAX_PAGES]; + u64 size; +}; + +/* + * Place holder for nest pmu events and values. + */ +struct ima_events { + char *ev_name; + char *ev_value; +}; + +/* + * Device tree parser code detects IMA pmu support and + * registers new IMA pmus. This structure will + * hold the pmu functions and attrs for each ima pmu and + * will be referenced at the time of pmu registration. + */ +struct ima_pmu { + struct pmu pmu; + int domain; + const struct attribute_group *attr_groups[4]; +}; + +/* + * Domains for IMA PMUs + */ +#define IMA_DOMAIN_NEST1 + +#define UNKNOWN_DOMAIN -1 + +#endif /* PPC_POWERNV_IMA_PMU_DEF_H */ -- 2.7.4
[PATCH v2 0/6] IMA Instrumentation Support
Power 9 has In-Memory-Accumulation (IMA) infrastructure which contains various Performance Monitoring Units (PMUs) at Nest level (these are on-chip but off-core). These Nest PMU counters are handled by a Nest IMA microcode. This microcode runs in the OCC (On-Chip Controller) complex and its purpose is to program the nest counters, collect the counter data and move the counter data to memory. The IMA infrastructure encapsulates nest (per-chip), core and thread level counters. While the nest IMA PMUs are handled by the nest IMA microcode, the core and thread level PMUs are handled by the Core-HPMC engine. This patchset enables the nest IMA PMUs and is based on the initial work done by Madhavan Srinivasan. "Nest Instrumentation Support" : https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-August/132078.html v1 for this patchset can be found here : https://lwn.net/Articles/705475/ Nest events: Per-chip nest instrumentation provides various per-chip metrics such as memory, powerbus, Xlink and Alink bandwidth. PMU Events' Information: OPAL obtains the Nest PMU and event information from the IMA Catalog and passes on to the kernel via the device tree. The events' information contains : - Event name - Event Offset - Event description and, maybe : - Event scale - Event unit Some PMUs may have a common scale and unit values for all their supported events. For those cases, the scale and unit properties for those events must be inherited from the PMU. The event offset in the memory is where the counter data gets accumulated. The OPAL-side patches are posted upstream : https://lists.ozlabs.org/pipermail/skiboot/2016-November/005552.html The kernel discovers the IMA counters information in the device tree at the "ima-counters" device node which has a compatible field "ibm,opal-in-memory-counters". Parsing of the Events' information: To parse the IMA PMUs and events information, the kernel has to discover the "ima-counters" node and walk through the pmu and event nodes. Here is an excerpt of the dt showing the ima-counters and mcs node: /dts-v1/; [...] ima-counters { ima-nest-offset = <0x32>; compatible = "ibm,opal-in-memory-counters"; ima-nest-size = <0x3>; #address-cells = <0x1>; #size-cells = <0x1>; phandle = <0x1238>; version-id = [00]; mcs0 { compatible = "ibm,ima-counters-chip"; ranges; #address-cells = <0x1>; #size-cells = <0x1>; phandle = <0x1279>; scale = "1.2207e-4"; unit = "MiB"; event@528 { event-name = "PM_MCS_UP_128B_DATA_XFER_MC0" ; desc = "Total Read Bandwidth seen on both MCS of MC0"; phandle = <0x128c>; reg = <0x118 0x8>; }; [...] >From the device tree, the kernel parses the PMUs and their events' information. After parsing the nest IMA PMUs and their events, the PMUs and their attributes are registered in the kernel. Example Usage : # perf list [...] nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0/ [Kernel PMU event] nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0_LAST_SAMPLE/ [Kernel PMU event] [...] # perf stat -e "nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0/" -a --per-socket TODOs: - Add support for Core IMA. - Add support for thread IMA. Comments/feedback/suggestions are welcome. Changelog: v1 -> v2 : - Account for the cases where a PMU can have a common scale and unit values for all its supported events (Patch 3/6). - Fixed a Build error (for maple_defconfig) by enabling ima_pmu.o only for CONFIG_PPC_POWERNV=y (Patch 4/6) - Read from the "event-name" property instead of "name" for an event node (Patch 3/6). Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Daniel Axtens Cc: Stephane Eranian Signed-off-by: Hemant Kumar Hemant Kumar (6): powerpc/powernv: Data structure and macros definitions powerpc/powernv: Autoload IMA device driver module powerpc/powernv: Detect supported IMA units and its events powerpc/perf: Add event attribute and group to IMA pmus powerpc/perf: Generic ima pmu event functions powerpc/perf: IMA pmu cpumask and cpu hotplug support arch/powerpc/include/asm/ima-pmu.h | 75 arch/powerpc/include/asm/opal-api.h| 3 +- arch/powerpc/include/asm/opal.h| 2 + arch/powerpc/perf/Makefile | 6 +- arch/powerpc/perf/ima-pmu.c
[PATCH v5 6/9] IB/hns: Replace counting semaphore event_sem with wait_event
Counting semaphores are going away in the future, so replace the semaphore mthca_cmd::event_sem with a conditional wait_event. Signed-off-by: Binoy Jayan --- drivers/infiniband/hw/hns/hns_roce_cmd.c| 46 - drivers/infiniband/hw/hns/hns_roce_device.h | 2 +- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c index 51a0675..12ef3d8 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cmd.c +++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c @@ -189,6 +189,34 @@ void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status, complete(>done); } +static inline struct hns_roce_cmd_context * +hns_roce_try_get_context(struct hns_roce_cmdq *cmd) +{ + struct hns_roce_cmd_context *context = NULL; + + spin_lock(>context_lock); + + if (cmd->free_head < 0) + goto out; + + context = >context[cmd->free_head]; + context->token += cmd->token_mask + 1; + cmd->free_head = context->next; +out: + spin_unlock(>context_lock); + return context; +} + +/* wait for and acquire a free context */ +static inline struct hns_roce_cmd_context * +hns_roce_get_free_context(struct hns_roce_cmdq *cmd) +{ + struct hns_roce_cmd_context *context; + + wait_event(cmd->wq, (context = hns_roce_try_get_context(cmd))); + return context; +} + /* this should be called with "use_events" */ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param, unsigned long in_modifier, @@ -200,13 +228,7 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, struct hns_roce_cmd_context *context; int ret = 0; - spin_lock(>context_lock); - WARN_ON(cmd->free_head < 0); - context = >context[cmd->free_head]; - context->token += cmd->token_mask + 1; - cmd->free_head = context->next; - spin_unlock(>context_lock); - + context = hns_roce_get_free_context(cmd); init_completion(>done); ret = hns_roce_cmd_mbox_post_hw(hr_dev, in_param, out_param, @@ -238,6 +260,7 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, context->next = cmd->free_head; cmd->free_head = context - cmd->context; spin_unlock(>context_lock); + wake_up(>wq); return ret; } @@ -248,10 +271,8 @@ static int hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param, { int ret = 0; - down(_dev->cmd.event_sem); ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param, in_modifier, op_modifier, op, timeout); - up(_dev->cmd.event_sem); return ret; } @@ -313,7 +334,7 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev) hr_cmd->context[hr_cmd->max_cmds - 1].next = -1; hr_cmd->free_head = 0; - sema_init(_cmd->event_sem, hr_cmd->max_cmds); + init_waitqueue_head(_cmd->wq); spin_lock_init(_cmd->context_lock); hr_cmd->token_mask = CMD_TOKEN_MASK; @@ -325,12 +346,9 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev) void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev) { struct hns_roce_cmdq *hr_cmd = _dev->cmd; - int i; hr_cmd->use_events = 0; - - for (i = 0; i < hr_cmd->max_cmds; ++i) - down(_cmd->event_sem); + hr_cmd->free_head = -1; kfree(hr_cmd->context); } diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 2afe075..ac95f52 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -364,7 +364,7 @@ struct hns_roce_cmdq { * Event mode: cmd register mutex protection, * ensure to not exceed max_cmds and user use limit region */ - struct semaphoreevent_sem; + wait_queue_head_t wq; int max_cmds; spinlock_t context_lock; int free_head; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 7/9] IB/mthca: Replace counting semaphore event_sem with wait_event
Counting semaphores are going away in the future, so replace the semaphore mthca_cmd::event_sem with a conditional wait_event. Signed-off-by: Binoy Jayan --- drivers/infiniband/hw/mthca/mthca_cmd.c | 47 ++--- drivers/infiniband/hw/mthca/mthca_dev.h | 3 ++- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 49c6e19..d6a048a 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -405,6 +405,34 @@ void mthca_cmd_event(struct mthca_dev *dev, complete(>done); } +static inline struct mthca_cmd_context * +mthca_try_get_context(struct mthca_cmd *cmd) +{ + struct mthca_cmd_context *context = NULL; + + spin_lock(>context_lock); + + if (cmd->free_head < 0) + goto out; + + context = >context[cmd->free_head]; + context->token += cmd->token_mask + 1; + cmd->free_head = context->next; +out: + spin_unlock(>context_lock); + return context; +} + +/* wait for and acquire a free context */ +static inline struct mthca_cmd_context * +mthca_get_free_context(struct mthca_cmd *cmd) +{ + struct mthca_cmd_context *context; + + wait_event(cmd->wq, (context = mthca_try_get_context(cmd))); + return context; +} + static int mthca_cmd_wait(struct mthca_dev *dev, u64 in_param, u64 *out_param, @@ -417,15 +445,7 @@ static int mthca_cmd_wait(struct mthca_dev *dev, int err = 0; struct mthca_cmd_context *context; - down(>cmd.event_sem); - - spin_lock(>cmd.context_lock); - BUG_ON(dev->cmd.free_head < 0); - context = >cmd.context[dev->cmd.free_head]; - context->token += dev->cmd.token_mask + 1; - dev->cmd.free_head = context->next; - spin_unlock(>cmd.context_lock); - + context = mthca_get_free_context(>cmd); init_completion(>done); err = mthca_cmd_post(dev, in_param, @@ -458,8 +478,8 @@ static int mthca_cmd_wait(struct mthca_dev *dev, context->next = dev->cmd.free_head; dev->cmd.free_head = context - dev->cmd.context; spin_unlock(>cmd.context_lock); + wake_up(>cmd.wq); - up(>cmd.event_sem); return err; } @@ -571,7 +591,7 @@ int mthca_cmd_use_events(struct mthca_dev *dev) dev->cmd.context[dev->cmd.max_cmds - 1].next = -1; dev->cmd.free_head = 0; - sema_init(>cmd.event_sem, dev->cmd.max_cmds); + init_waitqueue_head(>cmd.wq); spin_lock_init(>cmd.context_lock); for (dev->cmd.token_mask = 1; @@ -590,12 +610,9 @@ int mthca_cmd_use_events(struct mthca_dev *dev) */ void mthca_cmd_use_polling(struct mthca_dev *dev) { - int i; - dev->cmd.flags &= ~MTHCA_CMD_USE_EVENTS; - for (i = 0; i < dev->cmd.max_cmds; ++i) - down(>cmd.event_sem); + dev->cmd.free_head = -1; kfree(dev->cmd.context); } diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 87ab964..2fc86db 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -46,6 +46,7 @@ #include #include +#include #include "mthca_provider.h" #include "mthca_doorbell.h" @@ -121,7 +122,7 @@ struct mthca_cmd { struct pci_pool *pool; struct mutex hcr_mutex; struct mutex poll_mutex; - struct semaphore event_sem; + wait_queue_head_t wq; int max_cmds; spinlock_tcontext_lock; int free_head; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 8/9] IB/mlx5: Add helper mlx5_ib_post_send_wait
Clean up the following common code (to post a list of work requests to the send queue of the specified QP) at various places and add a helper function 'mlx5_ib_post_send_wait' to implement the same. - Initialize 'mlx5_ib_umr_context' on stack - Assign "mlx5_umr_wr:wr:wr_cqe to umr_context.cqe - Acquire the semaphore - call ib_post_send with a single ib_send_wr - wait_for_completion() - Check for umr_context.status - Release the semaphore As semaphores are going away in the future, moving all of these into the shared helper leaves only a single function using the semaphore, which can then be rewritten to use something else. Signed-off-by: Binoy Jayan --- drivers/infiniband/hw/mlx5/mr.c | 115 +++- 1 file changed, 32 insertions(+), 83 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index d4ad672..1593856 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -856,16 +856,40 @@ static inline void mlx5_ib_init_umr_context(struct mlx5_ib_umr_context *context) init_completion(>done); } +static inline int mlx5_ib_post_send_wait(struct mlx5_ib_dev *dev, +struct mlx5_umr_wr *umrwr) +{ + struct umr_common *umrc = >umrc; + struct ib_send_wr *bad; + int err; + struct mlx5_ib_umr_context umr_context; + + mlx5_ib_init_umr_context(_context); + umrwr->wr.wr_cqe = _context.cqe; + + down(>sem); + err = ib_post_send(umrc->qp, >wr, ); + if (err) { + mlx5_ib_warn(dev, "UMR post send failed, err %d\n", err); + } else { + wait_for_completion(_context.done); + if (umr_context.status != IB_WC_SUCCESS) { + mlx5_ib_warn(dev, "reg umr failed (%u)\n", +umr_context.status); + err = -EFAULT; + } + } + up(>sem); + return err; +} + static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, u64 virt_addr, u64 len, int npages, int page_shift, int order, int access_flags) { struct mlx5_ib_dev *dev = to_mdev(pd->device); struct device *ddev = dev->ib_dev.dma_device; - struct umr_common *umrc = >umrc; - struct mlx5_ib_umr_context umr_context; struct mlx5_umr_wr umrwr = {}; - struct ib_send_wr *bad; struct mlx5_ib_mr *mr; struct ib_sge sg; int size; @@ -894,24 +918,12 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, if (err) goto free_mr; - mlx5_ib_init_umr_context(_context); - - umrwr.wr.wr_cqe = _context.cqe; prep_umr_reg_wqe(pd, , , dma, npages, mr->mmkey.key, page_shift, virt_addr, len, access_flags); - down(>sem); - err = ib_post_send(umrc->qp, , ); - if (err) { - mlx5_ib_warn(dev, "post send failed, err %d\n", err); + err = mlx5_ib_post_send_wait(dev, ); + if (err && err != -EFAULT) goto unmap_dma; - } else { - wait_for_completion(_context.done); - if (umr_context.status != IB_WC_SUCCESS) { - mlx5_ib_warn(dev, "reg umr failed\n"); - err = -EFAULT; - } - } mr->mmkey.iova = virt_addr; mr->mmkey.size = len; @@ -920,7 +932,6 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, mr->live = 1; unmap_dma: - up(>sem); dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE); kfree(mr_pas); @@ -940,13 +951,10 @@ int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, int npages, { struct mlx5_ib_dev *dev = mr->dev; struct device *ddev = dev->ib_dev.dma_device; - struct umr_common *umrc = >umrc; - struct mlx5_ib_umr_context umr_context; struct ib_umem *umem = mr->umem; int size; __be64 *pas; dma_addr_t dma; - struct ib_send_wr *bad; struct mlx5_umr_wr wr; struct ib_sge sg; int err = 0; @@ -1011,10 +1019,7 @@ int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, int npages, dma_sync_single_for_device(ddev, dma, size, DMA_TO_DEVICE); - mlx5_ib_init_umr_context(_context); - memset(, 0, sizeof(wr)); - wr.wr.wr_cqe = _context.cqe; sg.addr = dma; sg.length = ALIGN(npages * sizeof(u64), @@ -1031,19 +1036,7 @@ int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, int npages, wr.mkey = mr->mmkey.key; wr.target.offset = start_page_index; - down(>sem); - err = ib_post_send(umrc->qp, , ); - if (err) { -
[PATCH v2 5/6] powerpc/perf: Generic ima pmu event functions
Since, the IMA counters' data are periodically fed to a memory location, the functions to read/update, start/stop, add/del can be generic and can be used by all IMA PMU units. This patch adds a set of generic ima pmu related event functions to be used by each ima pmu unit. Add code to setup format attribute and to register ima pmus. Add a event_init function for nest_ima events. Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- arch/powerpc/include/asm/ima-pmu.h| 2 + arch/powerpc/perf/ima-pmu.c | 122 ++ arch/powerpc/platforms/powernv/opal-ima.c | 37 +++-- 3 files changed, 154 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/ima-pmu.h b/arch/powerpc/include/asm/ima-pmu.h index 0ed8886..f0d95bb 100644 --- a/arch/powerpc/include/asm/ima-pmu.h +++ b/arch/powerpc/include/asm/ima-pmu.h @@ -70,4 +70,6 @@ struct ima_pmu { #define UNKNOWN_DOMAIN -1 +int ima_get_domain(struct device_node *pmu_dev); + #endif /* PPC_POWERNV_IMA_PMU_DEF_H */ diff --git a/arch/powerpc/perf/ima-pmu.c b/arch/powerpc/perf/ima-pmu.c index 50d2226..9948636 100644 --- a/arch/powerpc/perf/ima-pmu.c +++ b/arch/powerpc/perf/ima-pmu.c @@ -17,6 +17,117 @@ struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; struct ima_pmu *per_nest_pmu_arr[IMA_MAX_PMUS]; +/* Needed for sanity check */ +extern u64 nest_max_offset; + +PMU_FORMAT_ATTR(event, "config:0-20"); +static struct attribute *ima_format_attrs[] = { + _attr_event.attr, + NULL, +}; + +static struct attribute_group ima_format_group = { + .name = "format", + .attrs = ima_format_attrs, +}; + +static int nest_ima_event_init(struct perf_event *event) +{ + int chip_id; + u32 config = event->attr.config; + struct perchip_nest_info *pcni; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + /* Sanity check for config (event offset) */ + if (config > nest_max_offset) + return -EINVAL; + + chip_id = topology_physical_package_id(event->cpu); + pcni = _perchip_info[chip_id]; + event->hw.event_base = pcni->vbase[config/PAGE_SIZE] + + (config & ~PAGE_MASK); + + return 0; +} + +static void ima_read_counter(struct perf_event *event) +{ + u64 *addr, data; + + addr = (u64 *)event->hw.event_base; + data = __be64_to_cpu(*addr); + local64_set(>hw.prev_count, data); +} + +static void ima_perf_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count, *addr; + + addr = (u64 *)event->hw.event_base; + counter_prev = local64_read(>hw.prev_count); + counter_new = __be64_to_cpu(*addr); + final_count = counter_new - counter_prev; + + local64_set(>hw.prev_count, counter_new); + local64_add(final_count, >count); +} + +static void ima_event_start(struct perf_event *event, int flags) +{ + ima_read_counter(event); +} + +static void ima_event_stop(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_UPDATE) + ima_perf_event_update(event); +} + +static int ima_event_add(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_START) + ima_event_start(event, flags); + + return 0; +} + +/* update_pmu_ops : Populate the appropriate operations for "pmu" */ +static int update_pmu_ops(struct ima_pmu *pmu) +{ + if (!pmu) + return -EINVAL; + + pmu->pmu.task_ctx_nr = perf_invalid_context; + pmu->pmu.event_init = nest_ima_event_init; + pmu->pmu.add = ima_event_add; + pmu->pmu.del = ima_event_stop; + pmu->pmu.start = ima_event_start; + pmu->pmu.stop = ima_event_stop; + pmu->pmu.read = ima_perf_event_update; + pmu->attr_groups[1] = _format_group; + pmu->pmu.attr_groups = pmu->attr_groups; + + return 0; +} + /* dev_str_attr : Populate event "name" and string "str" in attribute */ static struct attribute *dev_str_attr(const char *name, const char *str) { @@ -83,6 +194,17 @@ int init_ima_pmu(struct ima_events *events, int idx, if (ret) goto err_free; + ret = update_pmu_ops(pmu_ptr); + if (ret) + goto
[PATCH v2 3/6] powerpc/powernv: Detect supported IMA units and its events
Parse device tree to detect IMA units. Traverse through each IMA unit node to find supported events and corresponding unit/scale files (if any). Right now, only nest IMA units are supported. The nest IMA unit event node from device tree will contain the offset in the reserved memory region to get the counter data for a given event. The offsets for the nest events are contained in the "reg" property of the event "node". Kernel code uses this offset as event configuration value. Device tree parser code also looks for scale/unit property in the event node and passes on the value as an event attr for perf interface to use in the post processing by the perf tool. Some PMUs may have common scale and unit properties which implies that all events supported by this PMU inherit the scale and unit properties of the PMU itself. For those events, we need to set the common unit and scale values. For failure to initialize any unit or any event, disable that unit and continue setting up the rest of them. Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- Changelog : v1 -> v2: - Read from the "event-name" property instead of "name" property for an event node. - Assign scale and unit values for events for a PMU which has a common unit and scale value. arch/powerpc/platforms/powernv/opal-ima.c | 332 ++ 1 file changed, 332 insertions(+) diff --git a/arch/powerpc/platforms/powernv/opal-ima.c b/arch/powerpc/platforms/powernv/opal-ima.c index 446e7bc..e8d5771 100644 --- a/arch/powerpc/platforms/powernv/opal-ima.c +++ b/arch/powerpc/platforms/powernv/opal-ima.c @@ -32,6 +32,337 @@ #include struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; +struct ima_pmu *per_nest_pmu_arr[IMA_MAX_PMUS]; + +static int ima_event_info(char *name, struct ima_events *events) +{ + char *buf; + + /* memory for content */ + buf = kzalloc(IMA_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + events->ev_name = name; + events->ev_value = buf; + return 0; +} + +static int ima_event_info_str(struct property *pp, char *name, + struct ima_events *events) +{ + int ret; + + ret = ima_event_info(name, events); + if (ret) + return ret; + + if (!pp->value || (strnlen(pp->value, pp->length) == pp->length) || + (pp->length > IMA_MAX_PMU_NAME_LEN)) + return -EINVAL; + strncpy(events->ev_value, (const char *)pp->value, pp->length); + + return 0; +} + +static int ima_event_info_val(char *name, u32 val, + struct ima_events *events) +{ + int ret; + + ret = ima_event_info(name, events); + if (ret) + return ret; + sprintf(events->ev_value, "event=0x%x", val); + + return 0; +} + +static int set_event_property(struct property *pp, char *event_prop, + struct ima_events *events, char *ev_name) +{ + char *buf; + int ret; + + buf = kzalloc(IMA_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + sprintf(buf, "%s.%s", ev_name, event_prop); + ret = ima_event_info_str(pp, buf, events); + if (ret) { + kfree(events->ev_name); + kfree(events->ev_value); + } + + return ret; +} + +/* + * ima_events_node_parser: Parse the event node "dev" and assign the parsed + * information to event "events". + * + * Parses the "reg" property of this event. "reg" gives us the event offset. + * Also, parse the "scale" and "unit" properties, if any. + */ +static int ima_events_node_parser(struct device_node *dev, + struct ima_events *events, + struct property *event_scale, + struct property *event_unit) +{ + struct property *name, *pp; + char *ev_name; + u32 val; + int idx = 0, ret; + + if (!dev) + return -EINVAL; + + /* +* Loop through each property of an event node +*/ + name = of_find_property(dev, "event-name", NULL); + if (!name) + return -ENODEV; + + if (!name->value || + (strnlen(name->value, name->length) == name->length) || + (name->length > IMA_MAX_PMU_NAME_LEN)) + return -EINVAL; + + ev_name = kzalloc(IMA_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!ev_name) + return -ENOMEM; + + strncpy(ev_name, name->value, name->length); + + /* +* Parse each property of this event node "dev". Property "reg" has +* the offset which is assigned to the event name. Other properties +* like "scale"
[PATCH v2 1/6] powerpc/powernv: Data structure and macros definitions
Create new header file "ima-pmu.h" to add the data structures and macros needed for IMA pmu support. Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- arch/powerpc/include/asm/ima-pmu.h | 73 ++ 1 file changed, 73 insertions(+) create mode 100644 arch/powerpc/include/asm/ima-pmu.h diff --git a/arch/powerpc/include/asm/ima-pmu.h b/arch/powerpc/include/asm/ima-pmu.h new file mode 100644 index 000..0ed8886 --- /dev/null +++ b/arch/powerpc/include/asm/ima-pmu.h @@ -0,0 +1,73 @@ +#ifndef PPC_POWERNV_IMA_PMU_DEF_H +#define PPC_POWERNV_IMA_PMU_DEF_H + +/* + * Nest Performance Monitor counter support. + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define IMA_MAX_CHIPS 32 +#define IMA_MAX_PMUS 32 +#define IMA_MAX_PMU_NAME_LEN 256 + +#define NEST_IMA_ENGINE_START 1 +#define NEST_IMA_ENGINE_STOP 0 +#define NEST_MAX_PAGES 16 + +#define NEST_IMA_PRODUCTION_MODE 1 + +#define IMA_DTB_COMPAT "ibm,opal-in-memory-counters" +#define IMA_DTB_NEST_COMPAT"ibm,ima-counters-chip" + +/* + * Structure to hold per chip specific memory address + * information for nest pmus. Nest Counter data are exported + * in per-chip reserved memory region by the PORE Engine. + */ +struct perchip_nest_info { + u32 chip_id; + u64 pbase; + u64 vbase[NEST_MAX_PAGES]; + u64 size; +}; + +/* + * Place holder for nest pmu events and values. + */ +struct ima_events { + char *ev_name; + char *ev_value; +}; + +/* + * Device tree parser code detects IMA pmu support and + * registers new IMA pmus. This structure will + * hold the pmu functions and attrs for each ima pmu and + * will be referenced at the time of pmu registration. + */ +struct ima_pmu { + struct pmu pmu; + int domain; + const struct attribute_group *attr_groups[4]; +}; + +/* + * Domains for IMA PMUs + */ +#define IMA_DOMAIN_NEST1 + +#define UNKNOWN_DOMAIN -1 + +#endif /* PPC_POWERNV_IMA_PMU_DEF_H */ -- 2.7.4
[PATCH v2 6/6] powerpc/perf: IMA pmu cpumask and cpu hotplug support
Adds cpumask attribute to be used by each IMA pmu. Only one cpu (any online CPU) from each chip for nest PMUs is designated to read counters. On CPU hotplug, dying CPU is checked to see whether it is one of the designated cpus, if yes, next online cpu from the same chip (for nest units) is designated as new cpu to read counters. Cc: Madhavan SrinivasanCc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- arch/powerpc/include/asm/opal-api.h| 3 +- arch/powerpc/include/asm/opal.h| 2 + arch/powerpc/perf/ima-pmu.c| 167 - arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + 4 files changed, 171 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 0e2e57b..116c155 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -167,7 +167,8 @@ #define OPAL_INT_EOI 124 #define OPAL_INT_SET_MFRR 125 #define OPAL_PCI_TCE_KILL 126 -#define OPAL_LAST 126 +#define OPAL_NEST_IMA_COUNTERS_CONTROL 128 +#define OPAL_LAST 128 /* Device tree flags */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index e958b70..bc31251 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -229,6 +229,8 @@ int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, int64_t opal_rm_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, uint32_t pe_num, uint32_t tce_size, uint64_t dma_addr, uint32_t npages); +int64_t opal_nest_ima_counters_control(uint64_t mode, uint64_t value1, + uint64_t value2, uint64_t value3); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, diff --git a/arch/powerpc/perf/ima-pmu.c b/arch/powerpc/perf/ima-pmu.c index 9948636..2b1bfc1 100644 --- a/arch/powerpc/perf/ima-pmu.c +++ b/arch/powerpc/perf/ima-pmu.c @@ -16,6 +16,7 @@ struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; struct ima_pmu *per_nest_pmu_arr[IMA_MAX_PMUS]; +static cpumask_t nest_ima_cpumask; /* Needed for sanity check */ extern u64 nest_max_offset; @@ -31,6 +32,164 @@ static struct attribute_group ima_format_group = { .attrs = ima_format_attrs, }; +/* Get the cpumask printed to a buffer "buf" */ +static ssize_t ima_pmu_cpumask_get_attr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + cpumask_t *active_mask; + + active_mask = _ima_cpumask; + return cpumap_print_to_pagebuf(true, buf, active_mask); +} + +static DEVICE_ATTR(cpumask, S_IRUGO, ima_pmu_cpumask_get_attr, NULL); + +static struct attribute *ima_pmu_cpumask_attrs[] = { + _attr_cpumask.attr, + NULL, +}; + +static struct attribute_group ima_pmu_cpumask_attr_group = { + .attrs = ima_pmu_cpumask_attrs, +}; + +/* + * nest_init : Initializes the nest ima engine for the current chip. + */ +static void nest_init(int *loc) +{ + int rc; + + rc = opal_nest_ima_counters_control(NEST_IMA_PRODUCTION_MODE, + NEST_IMA_ENGINE_START, 0, 0); + if (rc) + loc[smp_processor_id()] = 1; +} + +static void nest_change_cpu_context(int old_cpu, int new_cpu) +{ + int i; + + for (i = 0; +(per_nest_pmu_arr[i] != NULL) && (i < IMA_MAX_PMUS); i++) + perf_pmu_migrate_context(_nest_pmu_arr[i]->pmu, + old_cpu, new_cpu); +} + +static int ppc_nest_ima_cpu_online(unsigned int cpu) +{ + int nid, fcpu, ncpu; + struct cpumask *l_cpumask, tmp_mask; + + /* Fint the cpumask of this node */ + nid = cpu_to_node(cpu); + l_cpumask = cpumask_of_node(nid); + + /* +* If any of the cpu from this node is already present in the mask, +* just return, if not, then set this cpu in the mask. +*/ + if (!cpumask_and(_mask, l_cpumask, _ima_cpumask)) { + cpumask_set_cpu(cpu, _ima_cpumask); + return 0; + } + + fcpu = cpumask_first(l_cpumask); + ncpu = cpumask_next(cpu, l_cpumask); + if (cpu == fcpu) { + if (cpumask_test_and_clear_cpu(ncpu, _ima_cpumask)) { + cpumask_set_cpu(cpu, _ima_cpumask); +
[PATCH v5 9/9] IB/mlx5: Replace semaphore umr_common:sem with wait_event
Remove semaphore umr_common:sem used to limit concurrent access to umr qp and introduce an atomic value 'users' to keep track of the same. Use a wait_event to block when the limit is reached. Signed-off-by: Binoy Jayan--- drivers/infiniband/hw/mlx5/main.c| 6 +- drivers/infiniband/hw/mlx5/mlx5_ib.h | 7 ++- drivers/infiniband/hw/mlx5/mr.c | 6 -- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 63036c7..9de716c 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -2437,10 +2437,6 @@ static void destroy_umrc_res(struct mlx5_ib_dev *dev) ib_dealloc_pd(dev->umrc.pd); } -enum { - MAX_UMR_WR = 128, -}; - static int create_umr_res(struct mlx5_ib_dev *dev) { struct ib_qp_init_attr *init_attr = NULL; @@ -2520,7 +2516,7 @@ static int create_umr_res(struct mlx5_ib_dev *dev) dev->umrc.cq = cq; dev->umrc.pd = pd; - sema_init(>umrc.sem, MAX_UMR_WR); + init_waitqueue_head(>umrc.wq); ret = mlx5_mr_cache_init(dev); if (ret) { mlx5_ib_warn(dev, "mr cache init failed %d\n", ret); diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index dcdcd19..de31b5f 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -533,7 +533,12 @@ struct umr_common { struct ib_qp*qp; /* control access to UMR QP */ - struct semaphoresem; + wait_queue_head_t wq; + atomic_tusers; +}; + +enum { + MAX_UMR_WR = 128, }; enum { diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 1593856..dfaf6f6 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -867,7 +867,8 @@ static inline int mlx5_ib_post_send_wait(struct mlx5_ib_dev *dev, mlx5_ib_init_umr_context(_context); umrwr->wr.wr_cqe = _context.cqe; - down(>sem); + /* limit number of concurrent ib_post_send() on qp */ + wait_event(umrc->wq, atomic_add_unless(>users, 1, MAX_UMR_WR)); err = ib_post_send(umrc->qp, >wr, ); if (err) { mlx5_ib_warn(dev, "UMR post send failed, err %d\n", err); @@ -879,7 +880,8 @@ static inline int mlx5_ib_post_send_wait(struct mlx5_ib_dev *dev, err = -EFAULT; } } - up(>sem); + atomic_dec(>users); + wake_up(>wq); return err; } -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 3/9] IB/hns: Replace semaphore poll_sem with mutex
The semaphore 'poll_sem' is a simple mutex, so it should be written as one. Semaphores are going away in the future. So replace it with a mutex. Also, remove mutex_[un]lock from mthca_cmd_use_events and mthca_cmd_use_polling respectively. Signed-off-by: Binoy Jayan--- drivers/infiniband/hw/hns/hns_roce_cmd.c| 11 --- drivers/infiniband/hw/hns/hns_roce_device.h | 3 ++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c index 2a0b6c0..51a0675 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cmd.c +++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c @@ -119,7 +119,7 @@ static int hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev, u64 in_param, return ret; } -/* this should be called with "poll_sem" */ +/* this should be called with "poll_mutex" */ static int __hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param, unsigned long in_modifier, u8 op_modifier, u16 op, @@ -167,10 +167,10 @@ static int hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param, { int ret; - down(_dev->cmd.poll_sem); + mutex_lock(_dev->cmd.poll_mutex); ret = __hns_roce_cmd_mbox_poll(hr_dev, in_param, out_param, in_modifier, op_modifier, op, timeout); - up(_dev->cmd.poll_sem); + mutex_unlock(_dev->cmd.poll_mutex); return ret; } @@ -275,7 +275,7 @@ int hns_roce_cmd_init(struct hns_roce_dev *hr_dev) struct device *dev = _dev->pdev->dev; mutex_init(_dev->cmd.hcr_mutex); - sema_init(_dev->cmd.poll_sem, 1); + mutex_init(_dev->cmd.poll_mutex); hr_dev->cmd.use_events = 0; hr_dev->cmd.toggle = 1; hr_dev->cmd.max_cmds = CMD_MAX_NUM; @@ -319,8 +319,6 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev) hr_cmd->token_mask = CMD_TOKEN_MASK; hr_cmd->use_events = 1; - down(_cmd->poll_sem); - return 0; } @@ -335,7 +333,6 @@ void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev) down(_cmd->event_sem); kfree(hr_cmd->context); - up(_cmd->poll_sem); } struct hns_roce_cmd_mailbox diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 3417315..2afe075 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -34,6 +34,7 @@ #define _HNS_ROCE_DEVICE_H #include +#include #define DRV_NAME "hns_roce" @@ -358,7 +359,7 @@ struct hns_roce_cmdq { struct dma_pool *pool; u8 __iomem *hcr; struct mutexhcr_mutex; - struct semaphorepoll_sem; + struct mutexpoll_mutex; /* * Event mode: cmd register mutex protection, * ensure to not exceed max_cmds and user use limit region -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v2 6/6] powerpc/perf: IMA pmu cpumask and cpu hotplug support
Adds cpumask attribute to be used by each IMA pmu. Only one cpu (any online CPU) from each chip for nest PMUs is designated to read counters. On CPU hotplug, dying CPU is checked to see whether it is one of the designated cpus, if yes, next online cpu from the same chip (for nest units) is designated as new cpu to read counters. Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Anton Blanchard Cc: Sukadev Bhattiprolu Cc: Michael Neuling Cc: Stewart Smith Cc: Stephane Eranian Signed-off-by: Hemant Kumar --- arch/powerpc/include/asm/opal-api.h| 3 +- arch/powerpc/include/asm/opal.h| 2 + arch/powerpc/perf/ima-pmu.c| 167 - arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + 4 files changed, 171 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 0e2e57b..116c155 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -167,7 +167,8 @@ #define OPAL_INT_EOI 124 #define OPAL_INT_SET_MFRR 125 #define OPAL_PCI_TCE_KILL 126 -#define OPAL_LAST 126 +#define OPAL_NEST_IMA_COUNTERS_CONTROL 128 +#define OPAL_LAST 128 /* Device tree flags */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index e958b70..bc31251 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -229,6 +229,8 @@ int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, int64_t opal_rm_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, uint32_t pe_num, uint32_t tce_size, uint64_t dma_addr, uint32_t npages); +int64_t opal_nest_ima_counters_control(uint64_t mode, uint64_t value1, + uint64_t value2, uint64_t value3); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, diff --git a/arch/powerpc/perf/ima-pmu.c b/arch/powerpc/perf/ima-pmu.c index 9948636..2b1bfc1 100644 --- a/arch/powerpc/perf/ima-pmu.c +++ b/arch/powerpc/perf/ima-pmu.c @@ -16,6 +16,7 @@ struct perchip_nest_info nest_perchip_info[IMA_MAX_CHIPS]; struct ima_pmu *per_nest_pmu_arr[IMA_MAX_PMUS]; +static cpumask_t nest_ima_cpumask; /* Needed for sanity check */ extern u64 nest_max_offset; @@ -31,6 +32,164 @@ static struct attribute_group ima_format_group = { .attrs = ima_format_attrs, }; +/* Get the cpumask printed to a buffer "buf" */ +static ssize_t ima_pmu_cpumask_get_attr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + cpumask_t *active_mask; + + active_mask = _ima_cpumask; + return cpumap_print_to_pagebuf(true, buf, active_mask); +} + +static DEVICE_ATTR(cpumask, S_IRUGO, ima_pmu_cpumask_get_attr, NULL); + +static struct attribute *ima_pmu_cpumask_attrs[] = { + _attr_cpumask.attr, + NULL, +}; + +static struct attribute_group ima_pmu_cpumask_attr_group = { + .attrs = ima_pmu_cpumask_attrs, +}; + +/* + * nest_init : Initializes the nest ima engine for the current chip. + */ +static void nest_init(int *loc) +{ + int rc; + + rc = opal_nest_ima_counters_control(NEST_IMA_PRODUCTION_MODE, + NEST_IMA_ENGINE_START, 0, 0); + if (rc) + loc[smp_processor_id()] = 1; +} + +static void nest_change_cpu_context(int old_cpu, int new_cpu) +{ + int i; + + for (i = 0; +(per_nest_pmu_arr[i] != NULL) && (i < IMA_MAX_PMUS); i++) + perf_pmu_migrate_context(_nest_pmu_arr[i]->pmu, + old_cpu, new_cpu); +} + +static int ppc_nest_ima_cpu_online(unsigned int cpu) +{ + int nid, fcpu, ncpu; + struct cpumask *l_cpumask, tmp_mask; + + /* Fint the cpumask of this node */ + nid = cpu_to_node(cpu); + l_cpumask = cpumask_of_node(nid); + + /* +* If any of the cpu from this node is already present in the mask, +* just return, if not, then set this cpu in the mask. +*/ + if (!cpumask_and(_mask, l_cpumask, _ima_cpumask)) { + cpumask_set_cpu(cpu, _ima_cpumask); + return 0; + } + + fcpu = cpumask_first(l_cpumask); + ncpu = cpumask_next(cpu, l_cpumask); + if (cpu == fcpu) { + if (cpumask_test_and_clear_cpu(ncpu, _ima_cpumask)) { + cpumask_set_cpu(cpu, _ima_cpumask); + nest_change_cpu_context(ncpu, cpu); + } + } + + return 0; +} + +static int ppc_nest_ima_cpu_offline(unsigned int cpu) +{ + int nid, target = -1; + struct cpumask *l_cpumask; + + /* +* Check
[PATCH v5 9/9] IB/mlx5: Replace semaphore umr_common:sem with wait_event
Remove semaphore umr_common:sem used to limit concurrent access to umr qp and introduce an atomic value 'users' to keep track of the same. Use a wait_event to block when the limit is reached. Signed-off-by: Binoy Jayan --- drivers/infiniband/hw/mlx5/main.c| 6 +- drivers/infiniband/hw/mlx5/mlx5_ib.h | 7 ++- drivers/infiniband/hw/mlx5/mr.c | 6 -- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 63036c7..9de716c 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -2437,10 +2437,6 @@ static void destroy_umrc_res(struct mlx5_ib_dev *dev) ib_dealloc_pd(dev->umrc.pd); } -enum { - MAX_UMR_WR = 128, -}; - static int create_umr_res(struct mlx5_ib_dev *dev) { struct ib_qp_init_attr *init_attr = NULL; @@ -2520,7 +2516,7 @@ static int create_umr_res(struct mlx5_ib_dev *dev) dev->umrc.cq = cq; dev->umrc.pd = pd; - sema_init(>umrc.sem, MAX_UMR_WR); + init_waitqueue_head(>umrc.wq); ret = mlx5_mr_cache_init(dev); if (ret) { mlx5_ib_warn(dev, "mr cache init failed %d\n", ret); diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index dcdcd19..de31b5f 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -533,7 +533,12 @@ struct umr_common { struct ib_qp*qp; /* control access to UMR QP */ - struct semaphoresem; + wait_queue_head_t wq; + atomic_tusers; +}; + +enum { + MAX_UMR_WR = 128, }; enum { diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 1593856..dfaf6f6 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -867,7 +867,8 @@ static inline int mlx5_ib_post_send_wait(struct mlx5_ib_dev *dev, mlx5_ib_init_umr_context(_context); umrwr->wr.wr_cqe = _context.cqe; - down(>sem); + /* limit number of concurrent ib_post_send() on qp */ + wait_event(umrc->wq, atomic_add_unless(>users, 1, MAX_UMR_WR)); err = ib_post_send(umrc->qp, >wr, ); if (err) { mlx5_ib_warn(dev, "UMR post send failed, err %d\n", err); @@ -879,7 +880,8 @@ static inline int mlx5_ib_post_send_wait(struct mlx5_ib_dev *dev, err = -EFAULT; } } - up(>sem); + atomic_dec(>users); + wake_up(>wq); return err; } -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 3/9] IB/hns: Replace semaphore poll_sem with mutex
The semaphore 'poll_sem' is a simple mutex, so it should be written as one. Semaphores are going away in the future. So replace it with a mutex. Also, remove mutex_[un]lock from mthca_cmd_use_events and mthca_cmd_use_polling respectively. Signed-off-by: Binoy Jayan --- drivers/infiniband/hw/hns/hns_roce_cmd.c| 11 --- drivers/infiniband/hw/hns/hns_roce_device.h | 3 ++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c index 2a0b6c0..51a0675 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cmd.c +++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c @@ -119,7 +119,7 @@ static int hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev, u64 in_param, return ret; } -/* this should be called with "poll_sem" */ +/* this should be called with "poll_mutex" */ static int __hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param, unsigned long in_modifier, u8 op_modifier, u16 op, @@ -167,10 +167,10 @@ static int hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param, { int ret; - down(_dev->cmd.poll_sem); + mutex_lock(_dev->cmd.poll_mutex); ret = __hns_roce_cmd_mbox_poll(hr_dev, in_param, out_param, in_modifier, op_modifier, op, timeout); - up(_dev->cmd.poll_sem); + mutex_unlock(_dev->cmd.poll_mutex); return ret; } @@ -275,7 +275,7 @@ int hns_roce_cmd_init(struct hns_roce_dev *hr_dev) struct device *dev = _dev->pdev->dev; mutex_init(_dev->cmd.hcr_mutex); - sema_init(_dev->cmd.poll_sem, 1); + mutex_init(_dev->cmd.poll_mutex); hr_dev->cmd.use_events = 0; hr_dev->cmd.toggle = 1; hr_dev->cmd.max_cmds = CMD_MAX_NUM; @@ -319,8 +319,6 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev) hr_cmd->token_mask = CMD_TOKEN_MASK; hr_cmd->use_events = 1; - down(_cmd->poll_sem); - return 0; } @@ -335,7 +333,6 @@ void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev) down(_cmd->event_sem); kfree(hr_cmd->context); - up(_cmd->poll_sem); } struct hns_roce_cmd_mailbox diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 3417315..2afe075 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -34,6 +34,7 @@ #define _HNS_ROCE_DEVICE_H #include +#include #define DRV_NAME "hns_roce" @@ -358,7 +359,7 @@ struct hns_roce_cmdq { struct dma_pool *pool; u8 __iomem *hcr; struct mutexhcr_mutex; - struct semaphorepoll_sem; + struct mutexpoll_mutex; /* * Event mode: cmd register mutex protection, * ensure to not exceed max_cmds and user use limit region -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 1/9] IB/core: iwpm_nlmsg_request: Replace semaphore with completion
Semaphore sem in iwpm_nlmsg_request is used as completion, so convert it to a struct completion type. Semaphores are going away in the future. Signed-off-by: Binoy Jayan--- drivers/infiniband/core/iwpm_msg.c | 8 drivers/infiniband/core/iwpm_util.c | 7 +++ drivers/infiniband/core/iwpm_util.h | 3 ++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index 1c41b95..761358f 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c @@ -394,7 +394,7 @@ int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) /* always for found nlmsg_request */ kref_put(_request->kref, iwpm_free_nlmsg_request); barrier(); - up(_request->sem); + complete(_request->comp); return 0; } EXPORT_SYMBOL(iwpm_register_pid_cb); @@ -463,7 +463,7 @@ int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb) /* always for found request */ kref_put(_request->kref, iwpm_free_nlmsg_request); barrier(); - up(_request->sem); + complete(_request->comp); return 0; } EXPORT_SYMBOL(iwpm_add_mapping_cb); @@ -555,7 +555,7 @@ int iwpm_add_and_query_mapping_cb(struct sk_buff *skb, /* always for found request */ kref_put(_request->kref, iwpm_free_nlmsg_request); barrier(); - up(_request->sem); + complete(_request->comp); return 0; } EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); @@ -749,7 +749,7 @@ int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb) /* always for found request */ kref_put(_request->kref, iwpm_free_nlmsg_request); barrier(); - up(_request->sem); + complete(_request->comp); return 0; } EXPORT_SYMBOL(iwpm_mapping_error_cb); diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index ade71e7..08ddd2e 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -323,8 +323,7 @@ struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, nlmsg_request->nl_client = nl_client; nlmsg_request->request_done = 0; nlmsg_request->err_code = 0; - sema_init(_request->sem, 1); - down(_request->sem); + init_completion(_request->comp); return nlmsg_request; } @@ -368,8 +367,8 @@ int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request) { int ret; - ret = down_timeout(_request->sem, IWPM_NL_TIMEOUT); - if (ret) { + ret = wait_for_completion_timeout(_request->comp, IWPM_NL_TIMEOUT); + if (!ret) { ret = -EINVAL; pr_info("%s: Timeout %d sec for netlink request (seq = %u)\n", __func__, (IWPM_NL_TIMEOUT/HZ), nlmsg_request->nlmsg_seq); diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h index af1fc14..ea6c299 100644 --- a/drivers/infiniband/core/iwpm_util.h +++ b/drivers/infiniband/core/iwpm_util.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -69,7 +70,7 @@ struct iwpm_nlmsg_request { u8 nl_client; u8 request_done; u16 err_code; - struct semaphoresem; + struct completion comp; struct kref kref; }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 0/9] infiniband: Remove semaphores
Hi, These are a set of patches [v5] which removes semaphores from infiniband. These are part of a bigger effort to eliminate all semaphores from the linux kernel. v4 --> v5 - IB/isert: Replace semaphore sem with completion - Modified changelog to support use of completion IB/mlx5: Simplify completion into a wait_event - Avoid this patch. As umr_context is on the stack, and we are waiting for it to be fully done, it really should be a completion. v3 -> v4: - IB/mlx5: Added patch - Replace semaphore umr_common:sem with wait_event IB/mlx5: Fixed a bug pointed out by Leon Romanovsky v2 -> v3: - IB/mlx5: Move '_context' into helper fn IB/mthca: Restructure mthca_cmd.c to manage free_head IB/hns: Restructure hns_roce_cmd.c to manage free_head IB/core: Convert completion to wait_event IB/mlx5: Simplify completion into a wait_event v1 -> v2: - IB/hns : Use wait_event instead of open coding counting semaphores IB/mthca : Use wait_event instead of open coding counting semaphores IB/mthca : Remove mutex_[un]lock from *_cmd_use_events/*_cmd_use_polling IB/mlx5 : Cleanup, add helper mlx5_ib_post_send_wait v1 - IB/core: iwpm_nlmsg_request: Replace semaphore with completion IB/core: Replace semaphore sm_sem with completion IB/hns: Replace semaphore poll_sem with mutex IB/mthca: Replace semaphore poll_sem with mutex IB/isert: Replace semaphore sem with completion IB/hns: Replace counting semaphore event_sem with wait condition IB/mthca: Replace counting semaphore event_sem with wait condition IB/mlx5: Replace counting semaphore sem with wait condition Thanks, Binoy Binoy Jayan (9): IB/core: iwpm_nlmsg_request: Replace semaphore with completion IB/core: Replace semaphore sm_sem with an atomic wait IB/hns: Replace semaphore poll_sem with mutex IB/mthca: Replace semaphore poll_sem with mutex IB/isert: Replace semaphore sem with completion IB/hns: Replace counting semaphore event_sem with wait_event IB/mthca: Replace counting semaphore event_sem with wait_event IB/mlx5: Add helper mlx5_ib_post_send_wait IB/mlx5: Replace semaphore umr_common:sem with wait_event drivers/infiniband/core/iwpm_msg.c | 8 +- drivers/infiniband/core/iwpm_util.c | 7 +- drivers/infiniband/core/iwpm_util.h | 3 +- drivers/infiniband/core/user_mad.c | 20 +++-- drivers/infiniband/hw/hns/hns_roce_cmd.c| 57 +- drivers/infiniband/hw/hns/hns_roce_device.h | 5 +- drivers/infiniband/hw/mlx5/main.c | 6 +- drivers/infiniband/hw/mlx5/mlx5_ib.h| 7 +- drivers/infiniband/hw/mlx5/mr.c | 117 drivers/infiniband/hw/mthca/mthca_cmd.c | 57 -- drivers/infiniband/hw/mthca/mthca_cmd.h | 1 + drivers/infiniband/hw/mthca/mthca_dev.h | 5 +- drivers/infiniband/ulp/isert/ib_isert.c | 6 +- drivers/infiniband/ulp/isert/ib_isert.h | 3 +- 14 files changed, 147 insertions(+), 155 deletions(-) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 1/9] IB/core: iwpm_nlmsg_request: Replace semaphore with completion
Semaphore sem in iwpm_nlmsg_request is used as completion, so convert it to a struct completion type. Semaphores are going away in the future. Signed-off-by: Binoy Jayan --- drivers/infiniband/core/iwpm_msg.c | 8 drivers/infiniband/core/iwpm_util.c | 7 +++ drivers/infiniband/core/iwpm_util.h | 3 ++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index 1c41b95..761358f 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c @@ -394,7 +394,7 @@ int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) /* always for found nlmsg_request */ kref_put(_request->kref, iwpm_free_nlmsg_request); barrier(); - up(_request->sem); + complete(_request->comp); return 0; } EXPORT_SYMBOL(iwpm_register_pid_cb); @@ -463,7 +463,7 @@ int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb) /* always for found request */ kref_put(_request->kref, iwpm_free_nlmsg_request); barrier(); - up(_request->sem); + complete(_request->comp); return 0; } EXPORT_SYMBOL(iwpm_add_mapping_cb); @@ -555,7 +555,7 @@ int iwpm_add_and_query_mapping_cb(struct sk_buff *skb, /* always for found request */ kref_put(_request->kref, iwpm_free_nlmsg_request); barrier(); - up(_request->sem); + complete(_request->comp); return 0; } EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); @@ -749,7 +749,7 @@ int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb) /* always for found request */ kref_put(_request->kref, iwpm_free_nlmsg_request); barrier(); - up(_request->sem); + complete(_request->comp); return 0; } EXPORT_SYMBOL(iwpm_mapping_error_cb); diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index ade71e7..08ddd2e 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -323,8 +323,7 @@ struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, nlmsg_request->nl_client = nl_client; nlmsg_request->request_done = 0; nlmsg_request->err_code = 0; - sema_init(_request->sem, 1); - down(_request->sem); + init_completion(_request->comp); return nlmsg_request; } @@ -368,8 +367,8 @@ int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request) { int ret; - ret = down_timeout(_request->sem, IWPM_NL_TIMEOUT); - if (ret) { + ret = wait_for_completion_timeout(_request->comp, IWPM_NL_TIMEOUT); + if (!ret) { ret = -EINVAL; pr_info("%s: Timeout %d sec for netlink request (seq = %u)\n", __func__, (IWPM_NL_TIMEOUT/HZ), nlmsg_request->nlmsg_seq); diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h index af1fc14..ea6c299 100644 --- a/drivers/infiniband/core/iwpm_util.h +++ b/drivers/infiniband/core/iwpm_util.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -69,7 +70,7 @@ struct iwpm_nlmsg_request { u8 nl_client; u8 request_done; u16 err_code; - struct semaphoresem; + struct completion comp; struct kref kref; }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v5 0/9] infiniband: Remove semaphores
Hi, These are a set of patches [v5] which removes semaphores from infiniband. These are part of a bigger effort to eliminate all semaphores from the linux kernel. v4 --> v5 - IB/isert: Replace semaphore sem with completion - Modified changelog to support use of completion IB/mlx5: Simplify completion into a wait_event - Avoid this patch. As umr_context is on the stack, and we are waiting for it to be fully done, it really should be a completion. v3 -> v4: - IB/mlx5: Added patch - Replace semaphore umr_common:sem with wait_event IB/mlx5: Fixed a bug pointed out by Leon Romanovsky v2 -> v3: - IB/mlx5: Move '_context' into helper fn IB/mthca: Restructure mthca_cmd.c to manage free_head IB/hns: Restructure hns_roce_cmd.c to manage free_head IB/core: Convert completion to wait_event IB/mlx5: Simplify completion into a wait_event v1 -> v2: - IB/hns : Use wait_event instead of open coding counting semaphores IB/mthca : Use wait_event instead of open coding counting semaphores IB/mthca : Remove mutex_[un]lock from *_cmd_use_events/*_cmd_use_polling IB/mlx5 : Cleanup, add helper mlx5_ib_post_send_wait v1 - IB/core: iwpm_nlmsg_request: Replace semaphore with completion IB/core: Replace semaphore sm_sem with completion IB/hns: Replace semaphore poll_sem with mutex IB/mthca: Replace semaphore poll_sem with mutex IB/isert: Replace semaphore sem with completion IB/hns: Replace counting semaphore event_sem with wait condition IB/mthca: Replace counting semaphore event_sem with wait condition IB/mlx5: Replace counting semaphore sem with wait condition Thanks, Binoy Binoy Jayan (9): IB/core: iwpm_nlmsg_request: Replace semaphore with completion IB/core: Replace semaphore sm_sem with an atomic wait IB/hns: Replace semaphore poll_sem with mutex IB/mthca: Replace semaphore poll_sem with mutex IB/isert: Replace semaphore sem with completion IB/hns: Replace counting semaphore event_sem with wait_event IB/mthca: Replace counting semaphore event_sem with wait_event IB/mlx5: Add helper mlx5_ib_post_send_wait IB/mlx5: Replace semaphore umr_common:sem with wait_event drivers/infiniband/core/iwpm_msg.c | 8 +- drivers/infiniband/core/iwpm_util.c | 7 +- drivers/infiniband/core/iwpm_util.h | 3 +- drivers/infiniband/core/user_mad.c | 20 +++-- drivers/infiniband/hw/hns/hns_roce_cmd.c| 57 +- drivers/infiniband/hw/hns/hns_roce_device.h | 5 +- drivers/infiniband/hw/mlx5/main.c | 6 +- drivers/infiniband/hw/mlx5/mlx5_ib.h| 7 +- drivers/infiniband/hw/mlx5/mr.c | 117 drivers/infiniband/hw/mthca/mthca_cmd.c | 57 -- drivers/infiniband/hw/mthca/mthca_cmd.h | 1 + drivers/infiniband/hw/mthca/mthca_dev.h | 5 +- drivers/infiniband/ulp/isert/ib_isert.c | 6 +- drivers/infiniband/ulp/isert/ib_isert.h | 3 +- 14 files changed, 147 insertions(+), 155 deletions(-) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH V2 2/2] pinctrl: tegra: Add driver to configure voltage and power of io pads
Hi Laxman, [auto build test ERROR on tegra/for-next] [also build test ERROR on v4.9-rc6 next-20161117] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Laxman-Dewangan/pinctrl-tegra-Add-support-for-IO-pad-control/20161109-215733 base: https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next config: arm-allmodconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): drivers/pinctrl/tegra/pinctrl-tegra-io-pad.c: In function 'tegra_io_pad_pinconf_get': >> drivers/pinctrl/tegra/pinctrl-tegra-io-pad.c:113:9: error: implicit >> declaration of function 'tegra_io_pad_power_get_status' >> [-Werror=implicit-function-declaration] ret = tegra_io_pad_power_get_status(pad_id); ^ cc1: some warnings being treated as errors vim +/tegra_io_pad_power_get_status +113 drivers/pinctrl/tegra/pinctrl-tegra-io-pad.c 107 enum tegra_io_pad pad_id = pads_cfg->pad_id; 108 int arg = 0; 109 int ret; 110 111 switch (param) { 112 case PIN_CONFIG_LOW_POWER_MODE: > 113 ret = tegra_io_pad_power_get_status(pad_id); 114 if (ret < 0) 115 return ret; 116 arg = !ret; --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH V2 2/2] pinctrl: tegra: Add driver to configure voltage and power of io pads
Hi Laxman, [auto build test ERROR on tegra/for-next] [also build test ERROR on v4.9-rc6 next-20161117] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Laxman-Dewangan/pinctrl-tegra-Add-support-for-IO-pad-control/20161109-215733 base: https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next config: arm-allmodconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): drivers/pinctrl/tegra/pinctrl-tegra-io-pad.c: In function 'tegra_io_pad_pinconf_get': >> drivers/pinctrl/tegra/pinctrl-tegra-io-pad.c:113:9: error: implicit >> declaration of function 'tegra_io_pad_power_get_status' >> [-Werror=implicit-function-declaration] ret = tegra_io_pad_power_get_status(pad_id); ^ cc1: some warnings being treated as errors vim +/tegra_io_pad_power_get_status +113 drivers/pinctrl/tegra/pinctrl-tegra-io-pad.c 107 enum tegra_io_pad pad_id = pads_cfg->pad_id; 108 int arg = 0; 109 int ret; 110 111 switch (param) { 112 case PIN_CONFIG_LOW_POWER_MODE: > 113 ret = tegra_io_pad_power_get_status(pad_id); 114 if (ret < 0) 115 return ret; 116 arg = !ret; --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH v2 2/4] spi: spi-fsl-dspi: Fix continuous selection format
Current DMA implementation was not handling the continuous selection format viz. SPI chip select would be deasserted even between sequential serial transfers. Use the cs_change variable and correctly set or reset the CONT bit accordingly for case where peripherals require the chip select to be asserted between sequential transfers. Signed-off-by: Sanchayan Maity--- drivers/spi/spi-fsl-dspi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index b1ee1f5..41422cd 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -261,6 +261,8 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) | SPI_PUSHR_CTAS(0); + if (!dspi->cs_change) + dspi->dma->tx_dma_buf[i] |= SPI_PUSHR_CONT; dspi->tx += tx_word + 1; dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, -- 2.10.2
[PATCH v2 4/4] spi: spi-fsl-dspi: Minor code cleanup and error path fixes
Code cleanup for improving code readability and error path fixes and cleanup removing use of devm_kfree. Signed-off-by: Sanchayan Maity--- drivers/spi/spi-fsl-dspi.c | 22 -- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 08882f7..2987a16 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -226,8 +226,10 @@ static void dspi_rx_dma_callback(void *arg) if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) { for (i = 0; i < dma->curr_xfer_len; i++) { d = dspi->dma->rx_dma_buf[i]; - rx_word ? (*(u16 *)dspi->rx = d) : - (*(u8 *)dspi->rx = d); + if (rx_word) + *(u16 *)dspi->rx = d; + else + *(u8 *)dspi->rx = d; dspi->rx += rx_word + 1; } } @@ -247,14 +249,20 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) tx_word = is_double_byte_mode(dspi); for (i = 0; i < dma->curr_xfer_len - 1; i++) { - val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx; + if (tx_word) + val = *(u16 *) dspi->tx; + else + val = *(u8 *) dspi->tx; dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; dspi->tx += tx_word + 1; } - val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx; + if (tx_word) + val = *(u16 *) dspi->tx; + else + val = *(u8 *) dspi->tx; dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) | SPI_PUSHR_CTAS(0); @@ -430,9 +438,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) return 0; err_slave_config: - devm_kfree(dev, dma->rx_dma_buf); + dma_free_coherent(dev, DSPI_DMA_BUFSIZE, + dma->rx_dma_buf, dma->rx_dma_phys); err_rx_dma_buf: - devm_kfree(dev, dma->tx_dma_buf); + dma_free_coherent(dev, DSPI_DMA_BUFSIZE, + dma->tx_dma_buf, dma->tx_dma_phys); err_tx_dma_buf: dma_release_channel(dma->chan_tx); err_tx_channel: -- 2.10.2