2424#include <linux/bitops.h>
2525#include <linux/cpufeature.h>
2626#include <linux/cpumask.h>
27+ #include <linux/delay.h>
2728#include <linux/gfp.h>
2829#include <linux/io.h>
2930#include <linux/kernel.h>
@@ -347,6 +348,52 @@ static void init_hfi_instance(struct hfi_instance *hfi_instance)
347348 hfi_instance -> data = hfi_instance -> hdr + hfi_features .hdr_size ;
348349}
349350
351+ /* Caller must hold hfi_instance_lock. */
352+ static void hfi_enable (void )
353+ {
354+ u64 msr_val ;
355+
356+ rdmsrl (MSR_IA32_HW_FEEDBACK_CONFIG , msr_val );
357+ msr_val |= HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT ;
358+ wrmsrl (MSR_IA32_HW_FEEDBACK_CONFIG , msr_val );
359+ }
360+
361+ static void hfi_set_hw_table (struct hfi_instance * hfi_instance )
362+ {
363+ phys_addr_t hw_table_pa ;
364+ u64 msr_val ;
365+
366+ hw_table_pa = virt_to_phys (hfi_instance -> hw_table );
367+ msr_val = hw_table_pa | HW_FEEDBACK_PTR_VALID_BIT ;
368+ wrmsrl (MSR_IA32_HW_FEEDBACK_PTR , msr_val );
369+ }
370+
371+ /* Caller must hold hfi_instance_lock. */
372+ static void hfi_disable (void )
373+ {
374+ u64 msr_val ;
375+ int i ;
376+
377+ rdmsrl (MSR_IA32_HW_FEEDBACK_CONFIG , msr_val );
378+ msr_val &= ~HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT ;
379+ wrmsrl (MSR_IA32_HW_FEEDBACK_CONFIG , msr_val );
380+
381+ /*
382+ * Wait for hardware to acknowledge the disabling of HFI. Some
383+ * processors may not do it. Wait for ~2ms. This is a reasonable
384+ * time for hardware to complete any pending actions on the HFI
385+ * memory.
386+ */
387+ for (i = 0 ; i < 2000 ; i ++ ) {
388+ rdmsrl (MSR_IA32_PACKAGE_THERM_STATUS , msr_val );
389+ if (msr_val & PACKAGE_THERM_STATUS_HFI_UPDATED )
390+ break ;
391+
392+ udelay (1 );
393+ cpu_relax ();
394+ }
395+ }
396+
350397/**
351398 * intel_hfi_online() - Enable HFI on @cpu
352399 * @cpu: CPU in which the HFI will be enabled
@@ -364,8 +411,6 @@ void intel_hfi_online(unsigned int cpu)
364411{
365412 struct hfi_instance * hfi_instance ;
366413 struct hfi_cpu_info * info ;
367- phys_addr_t hw_table_pa ;
368- u64 msr_val ;
369414 u16 die_id ;
370415
371416 /* Nothing to do if hfi_instances are missing. */
@@ -392,25 +437,26 @@ void intel_hfi_online(unsigned int cpu)
392437 /*
393438 * Now check if the HFI instance of the package/die of @cpu has been
394439 * initialized (by checking its header). In such case, all we have to
395- * do is to add @cpu to this instance's cpumask.
440+ * do is to add @cpu to this instance's cpumask and enable the instance
441+ * if needed.
396442 */
397443 mutex_lock (& hfi_instance_lock );
398- if (hfi_instance -> hdr ) {
399- cpumask_set_cpu (cpu , hfi_instance -> cpus );
400- goto unlock ;
401- }
444+ if (hfi_instance -> hdr )
445+ goto enable ;
402446
403447 /*
404448 * Hardware is programmed with the physical address of the first page
405449 * frame of the table. Hence, the allocated memory must be page-aligned.
450+ *
451+ * Some processors do not forget the initial address of the HFI table
452+ * even after having been reprogrammed. Keep using the same pages. Do
453+ * not free them.
406454 */
407455 hfi_instance -> hw_table = alloc_pages_exact (hfi_features .nr_table_pages ,
408456 GFP_KERNEL | __GFP_ZERO );
409457 if (!hfi_instance -> hw_table )
410458 goto unlock ;
411459
412- hw_table_pa = virt_to_phys (hfi_instance -> hw_table );
413-
414460 /*
415461 * Allocate memory to keep a local copy of the table that
416462 * hardware generates.
@@ -420,31 +466,20 @@ void intel_hfi_online(unsigned int cpu)
420466 if (!hfi_instance -> local_table )
421467 goto free_hw_table ;
422468
423- /*
424- * Program the address of the feedback table of this die/package. On
425- * some processors, hardware remembers the old address of the HFI table
426- * even after having been reprogrammed and re-enabled. Thus, do not free
427- * the pages allocated for the table or reprogram the hardware with a
428- * new base address. Namely, program the hardware only once.
429- */
430- msr_val = hw_table_pa | HW_FEEDBACK_PTR_VALID_BIT ;
431- wrmsrl (MSR_IA32_HW_FEEDBACK_PTR , msr_val );
432-
433469 init_hfi_instance (hfi_instance );
434470
435471 INIT_DELAYED_WORK (& hfi_instance -> update_work , hfi_update_work_fn );
436472 raw_spin_lock_init (& hfi_instance -> table_lock );
437473 raw_spin_lock_init (& hfi_instance -> event_lock );
438474
475+ enable :
439476 cpumask_set_cpu (cpu , hfi_instance -> cpus );
440477
441- /*
442- * Enable the hardware feedback interface and never disable it. See
443- * comment on programming the address of the table.
444- */
445- rdmsrl (MSR_IA32_HW_FEEDBACK_CONFIG , msr_val );
446- msr_val |= HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT ;
447- wrmsrl (MSR_IA32_HW_FEEDBACK_CONFIG , msr_val );
478+ /* Enable this HFI instance if this is its first online CPU. */
479+ if (cpumask_weight (hfi_instance -> cpus ) == 1 ) {
480+ hfi_set_hw_table (hfi_instance );
481+ hfi_enable ();
482+ }
448483
449484unlock :
450485 mutex_unlock (& hfi_instance_lock );
@@ -484,6 +519,10 @@ void intel_hfi_offline(unsigned int cpu)
484519
485520 mutex_lock (& hfi_instance_lock );
486521 cpumask_clear_cpu (cpu , hfi_instance -> cpus );
522+
523+ if (!cpumask_weight (hfi_instance -> cpus ))
524+ hfi_disable ();
525+
487526 mutex_unlock (& hfi_instance_lock );
488527}
489528
0 commit comments