Print this page
XXXX cpudrv attach is racy


 260                     NULL) {
 261                         cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
 262                             "can't get state", instance);
 263                         ddi_soft_state_free(cpudrv_state, instance);
 264                         cpudrv_enabled = B_FALSE;
 265                         return (DDI_FAILURE);
 266                 }
 267                 cpudsp->dip = dip;
 268 
 269                 /*
 270                  * Find CPU number for this dev_info node.
 271                  */
 272                 if (!cpudrv_get_cpu_id(dip, &(cpudsp->cpu_id))) {
 273                         cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
 274                             "can't convert dip to cpu_id", instance);
 275                         ddi_soft_state_free(cpudrv_state, instance);
 276                         cpudrv_enabled = B_FALSE;
 277                         return (DDI_FAILURE);
 278                 }
 279 









 280                 mutex_init(&cpudsp->lock, NULL, MUTEX_DRIVER, NULL);
 281                 if (cpudrv_is_enabled(cpudsp)) {
 282                         if (cpudrv_init(cpudsp) != DDI_SUCCESS) {
 283                                 cpudrv_enabled = B_FALSE;
 284                                 cpudrv_free(cpudsp);
 285                                 ddi_soft_state_free(cpudrv_state, instance);
 286                                 return (DDI_FAILURE);
 287                         }
 288                         if (cpudrv_comp_create(cpudsp) != DDI_SUCCESS) {
 289                                 cpudrv_enabled = B_FALSE;
 290                                 cpudrv_free(cpudsp);
 291                                 ddi_soft_state_free(cpudrv_state, instance);
 292                                 return (DDI_FAILURE);
 293                         }
 294                         if (ddi_prop_update_string(DDI_DEV_T_NONE,
 295                             dip, "pm-class", "CPU") != DDI_PROP_SUCCESS) {
 296                                 cpudrv_enabled = B_FALSE;
 297                                 cpudrv_free(cpudsp);
 298                                 ddi_soft_state_free(cpudrv_state, instance);
 299                                 return (DDI_FAILURE);
 300                         }
 301 


 318                          * needed speed. We assume that initial needed speed
 319                          * is full speed for us.
 320                          */
 321                         /*
 322                          * We need to take the lock because cpudrv_monitor()
 323                          * will start running in parallel with attach().
 324                          */
 325                         mutex_enter(&cpudsp->lock);
 326                         cpudsp->cpudrv_pm.cur_spd = NULL;
 327                         cpudsp->cpudrv_pm.pm_started = B_FALSE;
 328                         /*
 329                          * We don't call pm_raise_power() directly from attach
 330                          * because driver attach for a slave CPU node can
 331                          * happen before the CPU is even initialized. We just
 332                          * start the monitoring system which understands
 333                          * unknown speed and moves CPU to top speed when it
 334                          * has been initialized.
 335                          */
 336                         CPUDRV_MONITOR_INIT(cpudsp);
 337                         mutex_exit(&cpudsp->lock);
 338 
 339                 }
 340 
 341                 if (!cpudrv_mach_init(cpudsp)) {
 342                         cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
 343                             "cpudrv_mach_init failed", instance);
 344                         cpudrv_enabled = B_FALSE;
 345                         cpudrv_free(cpudsp);
 346                         ddi_soft_state_free(cpudrv_state, instance);
 347                         return (DDI_FAILURE);
 348                 }
 349 
 350                 CPUDRV_INSTALL_MAX_CHANGE_HANDLER(cpudsp);
 351 
 352                 (void) ddi_prop_update_int(DDI_DEV_T_NONE, dip,
 353                     DDI_NO_AUTODETACH, 1);
 354                 ddi_report_dev(dip);
 355                 return (DDI_SUCCESS);
 356 
 357         case DDI_RESUME:
 358                 DPRINTF(D_ATTACH, ("cpudrv_attach: instance %d: "
 359                     "DDI_RESUME called\n", instance));




 260                     NULL) {
 261                         cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
 262                             "can't get state", instance);
 263                         ddi_soft_state_free(cpudrv_state, instance);
 264                         cpudrv_enabled = B_FALSE;
 265                         return (DDI_FAILURE);
 266                 }
 267                 cpudsp->dip = dip;
 268 
 269                 /*
 270                  * Find CPU number for this dev_info node.
 271                  */
 272                 if (!cpudrv_get_cpu_id(dip, &(cpudsp->cpu_id))) {
 273                         cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
 274                             "can't convert dip to cpu_id", instance);
 275                         ddi_soft_state_free(cpudrv_state, instance);
 276                         cpudrv_enabled = B_FALSE;
 277                         return (DDI_FAILURE);
 278                 }
 279 
 280                 if (!cpudrv_is_enabled(cpudsp)) {
 281                         cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
 282                             "not supported or it got disabled on us",
 283                             instance);
 284                         cpudrv_enabled = B_FALSE;
 285                         ddi_soft_state_free(cpudrv_state, instance);
 286                         return (DDI_FAILURE);
 287                 }
 288 
 289                 mutex_init(&cpudsp->lock, NULL, MUTEX_DRIVER, NULL);

 290                 if (cpudrv_init(cpudsp) != DDI_SUCCESS) {
 291                         cpudrv_enabled = B_FALSE;
 292                         cpudrv_free(cpudsp);
 293                         ddi_soft_state_free(cpudrv_state, instance);
 294                         return (DDI_FAILURE);
 295                 }
 296                 if (cpudrv_comp_create(cpudsp) != DDI_SUCCESS) {
 297                         cpudrv_enabled = B_FALSE;
 298                         cpudrv_free(cpudsp);
 299                         ddi_soft_state_free(cpudrv_state, instance);
 300                         return (DDI_FAILURE);
 301                 }
 302                 if (ddi_prop_update_string(DDI_DEV_T_NONE,
 303                     dip, "pm-class", "CPU") != DDI_PROP_SUCCESS) {
 304                         cpudrv_enabled = B_FALSE;
 305                         cpudrv_free(cpudsp);
 306                         ddi_soft_state_free(cpudrv_state, instance);
 307                         return (DDI_FAILURE);
 308                 }
 309 


 326                  * needed speed. We assume that initial needed speed
 327                  * is full speed for us.
 328                  */
 329                 /*
 330                  * We need to take the lock because cpudrv_monitor()
 331                  * will start running in parallel with attach().
 332                  */
 333                 mutex_enter(&cpudsp->lock);
 334                 cpudsp->cpudrv_pm.cur_spd = NULL;
 335                 cpudsp->cpudrv_pm.pm_started = B_FALSE;
 336                 /*
 337                  * We don't call pm_raise_power() directly from attach
 338                  * because driver attach for a slave CPU node can
 339                  * happen before the CPU is even initialized. We just
 340                  * start the monitoring system which understands
 341                  * unknown speed and moves CPU to top speed when it
 342                  * has been initialized.
 343                  */
 344                 CPUDRV_MONITOR_INIT(cpudsp);
 345                 mutex_exit(&cpudsp->lock);


 346 
 347                 if (!cpudrv_mach_init(cpudsp)) {
 348                         cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
 349                             "cpudrv_mach_init failed", instance);
 350                         cpudrv_enabled = B_FALSE;
 351                         cpudrv_free(cpudsp);
 352                         ddi_soft_state_free(cpudrv_state, instance);
 353                         return (DDI_FAILURE);
 354                 }
 355 
 356                 CPUDRV_INSTALL_MAX_CHANGE_HANDLER(cpudsp);
 357 
 358                 (void) ddi_prop_update_int(DDI_DEV_T_NONE, dip,
 359                     DDI_NO_AUTODETACH, 1);
 360                 ddi_report_dev(dip);
 361                 return (DDI_SUCCESS);
 362 
 363         case DDI_RESUME:
 364                 DPRINTF(D_ATTACH, ("cpudrv_attach: instance %d: "
 365                     "DDI_RESUME called\n", instance));